client: add tdm_client_handle_events_timeout 82/171382/3
authorBoram Park <boram1288.park@samsung.com>
Fri, 2 Mar 2018 07:38:27 +0000 (16:38 +0900)
committerBoram Park <boram1288.park@samsung.com>
Fri, 2 Mar 2018 08:22:58 +0000 (17:22 +0900)
Change-Id: Ifebfbe10670f7f8af366e26c8ea8e172f024d6a1

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

index d109f3a..b7328a8 100644 (file)
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <strings.h>
+#include <poll.h>
 
 #include "tdm_client.h"
 #include "tdm_log.h"
@@ -445,6 +446,90 @@ tdm_client_handle_events(tdm_client *client)
        return TDM_ERROR_NONE;
 }
 
+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 43edd41..b09bd66 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 054cb5e..ee86347 100644 (file)
@@ -68,6 +68,7 @@ typedef enum {
        TDM_ERROR_NO_CAPABILITY         = -9, /**< no capability */
        TDM_ERROR_DPMS_OFF              = -10, /**< dpms off */
        TDM_ERROR_OUTPUT_DISCONNECTED   = -11, /**< output disconnected */
+       TDM_ERROR_TIMEOUT               = -12, /**< timeout */
 } tdm_error;
 
 /**