client: add tdm_client_handle_events_timeout 86/171386/2
authorBoram Park <boram1288.park@samsung.com>
Fri, 2 Mar 2018 07:38:27 +0000 (16:38 +0900)
committerBoram Park <boram1288.park@samsung.com>
Wed, 7 Mar 2018 01:35:48 +0000 (10:35 +0900)
Change-Id: Ifebfbe10670f7f8af366e26c8ea8e172f024d6a1

client/tdm_client.c
client/tdm_client.h
include/tdm_common.h

index e71c691..84b4c07 100644 (file)
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <strings.h>
+#include <poll.h>
 
 #include <tdm-client-protocol.h>
 
@@ -570,6 +571,90 @@ tdm_client_handle_events(tdm_client *client)
        /* LCOV_EXCL_STOP */
 }
 
+static int
+_tdm_client_poll(struct wl_display *display, short int events, int timeout)
+{
+       int ret;
+       struct pollfd pfd[1];
+
+       pfd[0].fd = wl_display_get_fd(display);
+       pfd[0].events = events;
+       do {
+               ret = poll(pfd, 1, timeout);
+       } while (ret == -1 && errno == EINTR);
+
+       return ret;
+}
+
+static tdm_error
+_tdm_client_dispatch_timeout(tdm_private_client *private_client, int timeout)
+{
+       int ret;
+       struct wl_display *display = private_client->display;
+
+       if (wl_display_prepare_read(display) == -1)
+               return wl_display_dispatch_pending(display);
+
+       while (true) {
+               ret = wl_display_flush(display);
+
+               if (ret != -1 || errno != EAGAIN)
+                       break;
+
+               if (_tdm_client_poll(display, POLLOUT, -1) == -1) {
+                       wl_display_cancel_read(display);
+                       TDM_ERR("_tdm_client_poll failed");
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       /* Don't stop if flushing hits an EPIPE; continue so we can read any
+        * protocol error that may have triggered it. */
+       if (ret < 0 && errno != EPIPE) {
+               TDM_ERR("ret(%d) errno(%d)", ret, errno);
+               wl_display_cancel_read(display);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       ret = _tdm_client_poll(display, POLLIN, timeout);
+       if (ret <= 0) {
+               wl_display_cancel_read(display);
+               if (ret == 0) {
+                       TDM_ERR("_tdm_client_poll timeout.");
+                       return TDM_ERROR_TIMEOUT;
+               } else {
+                       TDM_ERR("_tdm_client_poll failed. (ret:%d)", ret);
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       if (wl_display_read_events(display) == -1) {
+               TDM_ERR("wl_display_read_events failed");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       ret = wl_display_dispatch_pending(display);
+
+       if (ret < 0) {
+               TDM_ERR("_tdm_client_dispatch_timeout failed");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout)
+{
+       tdm_private_client *private_client;
+
+       TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_client = (tdm_private_client*)client;
+
+       return _tdm_client_dispatch_timeout(private_client, ms_timeout);
+}
+
 typedef struct _tdm_client_vblank_temp {
        tdm_client_vblank_handler2 func;
        void *user_data;
index 4ef687b..2b9dc1e 100644 (file)
@@ -117,6 +117,18 @@ tdm_error
 tdm_client_handle_events(tdm_client *client);
 
 /**
+ * @brief Handle the events of the given file descriptor with millisecond timeout
+ * @details
+ * -1: infinite. 0: return immediately. Otherwise, waiting for ms_timeout milliseconds.
+ * @param[in] client A TDM client object
+ * @param[in] ms_timeout timeout value.
+ * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ * @see #tdm_client_get_fd
+ */
+tdm_error
+tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout);
+
+/**
  * @brief @b Deprecated. Wait for VBLANK.
  * @deprecated
  * @details After interval vblanks, a client vblank handler will be called.
index 4c264ed..db7e087 100644 (file)
@@ -69,6 +69,7 @@ typedef enum {
        TDM_ERROR_DPMS_OFF              = -10, /**< dpms off */
        TDM_ERROR_OUTPUT_DISCONNECTED   = -11, /**< output disconnected */
        TDM_ERROR_PROTOCOL_ERROR        = -12, /**< protocol error */
+       TDM_ERROR_TIMEOUT               = -13, /**< timeout */
 } tdm_error;
 
 /**