client: handling wayland protocol error 57/170457/1
authorBoram Park <boram1288.park@samsung.com>
Thu, 8 Feb 2018 05:04:02 +0000 (14:04 +0900)
committerBoram Park <boram1288.park@samsung.com>
Tue, 20 Feb 2018 06:16:43 +0000 (15:16 +0900)
Change-Id: I2d064e7808298820dd7e44f0c185aea673fa9999

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

index 51e5c5e..9d00023 100644 (file)
@@ -134,6 +134,30 @@ typedef struct _tdm_client_wait_info {
        struct list_head call_link;
 } tdm_client_wait_info;
 
+static unsigned int
+_tdm_client_check_wl_error(tdm_private_client *private_client, const char *func, int line)
+{
+       uint32_t ec, id;
+       const struct wl_interface *intf;
+       int err;
+
+       err = wl_display_get_error(private_client->display);
+       if (!err)
+               return false;
+
+       if (err == EINVAL || err == ENOMEM || err == EFAULT || err == EPROTO) {
+               ec = wl_display_get_protocol_error(private_client->display, &intf, &id);
+               TDM_ERR("[%s,%d] errno(%d) Got protocol error '%u' on interface '%s' (object '%u')",
+                               func, line, err, ec, (intf) ? intf->name : "destroyed", id);
+       } else {
+               TDM_ERR("[%s,%d] errno(%d)", func, line, err);
+       }
+
+       return true;
+}
+
+#define CHECK_WL_PROTOCOL_ERROR(pc)  _tdm_client_check_wl_error(pc, __FUNCTION__, __LINE__)
+
 static void
 _tdm_client_vblank_cb_stamp(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uint32_t stamp)
 {
@@ -435,6 +459,9 @@ tdm_client_create(tdm_error *error)
                                                         &tdm_client_registry_listener, private_client);
        wl_display_roundtrip(private_client->display);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client))
+               goto create_failed;
+
        /* check global objects */
        TDM_GOTO_IF_FAIL(private_client->tdm != NULL, create_failed);
 
@@ -516,6 +543,11 @@ tdm_client_handle_events(tdm_client *client)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (private_client->enable_ttrace)
                TDM_TRACE_ASYNC_BEGIN((int)private_client->stamp, "TDM_Client_Events:%u", (unsigned int)private_client->stamp);
 
@@ -524,6 +556,11 @@ tdm_client_handle_events(tdm_client *client)
        if (private_client->enable_ttrace)
                TDM_TRACE_ASYNC_END((int)private_client->stamp, "TDM_Client_Events:%u", (unsigned int)private_client->stamp);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        pthread_mutex_unlock(&private_client->lock);
 
        return TDM_ERROR_NONE;
@@ -575,6 +612,9 @@ tdm_client_wait_vblank(tdm_client *client, char *name,
        TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client))
+               return TDM_ERROR_PROTOCOL_ERROR;
+
        if (!private_client->temp_vblank) {
                output = tdm_client_get_output(client, name, &ret);
                TDM_RETURN_VAL_IF_FAIL(output != NULL, ret);
@@ -617,6 +657,13 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               if (error)
+                       *error = TDM_ERROR_PROTOCOL_ERROR;
+               pthread_mutex_unlock(&private_client->lock);
+               return NULL;
+       }
+
        if (!name)
                name = "primary";
 
@@ -671,7 +718,6 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error)
 
        LIST_INITHEAD(&private_output->vblank_list);
        LIST_INITHEAD(&private_output->change_handler_list);
-       LIST_ADDTAIL(&private_output->link, &private_client->output_list);
 
        wl_tdm_output_add_listener(private_output->output,
                                                           &tdm_client_output_listener, private_output);
@@ -679,6 +725,17 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error)
 
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               wl_tdm_output_destroy(private_output->output);
+               free(private_output);
+               if (error)
+                       *error = TDM_ERROR_PROTOCOL_ERROR;
+               pthread_mutex_unlock(&private_client->lock);
+               return NULL;
+       }
+
+       LIST_ADDTAIL(&private_output->link, &private_client->output_list);
+
        pthread_mutex_unlock(&private_client->lock);
 
        return (tdm_client_output*)private_output;
@@ -704,6 +761,12 @@ tdm_client_output_add_change_handler(tdm_client_output *output,
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               free(h);
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (LIST_IS_EMPTY(&private_output->change_handler_list)) {
                wl_tdm_output_watch_output_changes(private_output->output, 1);
 
@@ -751,8 +814,10 @@ tdm_client_output_remove_change_handler(tdm_client_output *output,
                LIST_DEL(&h->link);
                free(h);
 
-               if (LIST_IS_EMPTY(&private_output->change_handler_list))
-                       wl_tdm_output_watch_output_changes(private_output->output, 0);
+               if (LIST_IS_EMPTY(&private_output->change_handler_list)) {
+                       if (!CHECK_WL_PROTOCOL_ERROR(private_client))
+                               wl_tdm_output_watch_output_changes(private_output->output, 0);
+               }
 
                pthread_mutex_unlock(&private_client->lock);
 
@@ -782,11 +847,21 @@ tdm_client_output_get_refresh_rate(tdm_client_output *output, unsigned int *refr
                return TDM_ERROR_NONE;
        }
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, private_client->queue);
        wl_tdm_output_get_mode(private_output->output);
        wl_display_roundtrip_queue(private_client->display, private_client->queue);
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        *refresh = private_output->refresh;
 
        pthread_mutex_unlock(&private_client->lock);
@@ -814,11 +889,21 @@ tdm_client_output_get_conn_status(tdm_client_output *output, tdm_output_conn_sta
                return TDM_ERROR_NONE;
        }
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, private_client->queue);
        wl_tdm_output_get_connection(private_output->output);
        wl_display_roundtrip_queue(private_client->display, private_client->queue);
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        *status = private_output->connection;
 
        pthread_mutex_unlock(&private_client->lock);
@@ -845,11 +930,21 @@ tdm_client_output_get_dpms(tdm_client_output *output, tdm_output_dpms *dpms)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, private_client->queue);
        wl_tdm_output_get_dpms(private_output->output);
        wl_display_roundtrip_queue(private_client->display, private_client->queue);
        wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        *dpms = private_output->dpms;
 
        pthread_mutex_unlock(&private_client->lock);
@@ -880,6 +975,13 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               if (error)
+                       *error = TDM_ERROR_PROTOCOL_ERROR;
+               pthread_mutex_unlock(&private_client->lock);
+               return NULL;
+       }
+
        wrapper = wl_proxy_create_wrapper(private_output->output);
        if (!wrapper) {
                TDM_ERR("create output_wrapper failed");
@@ -928,7 +1030,6 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error)
        private_vblank->enable_fake = 0;
 
        LIST_INITHEAD(&private_vblank->wait_list);
-       LIST_ADDTAIL(&private_vblank->link, &private_output->vblank_list);
 
        wl_tdm_vblank_add_listener(private_vblank->vblank,
                                                           &tdm_client_vblank_listener, private_vblank);
@@ -936,6 +1037,17 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error)
 
        wl_proxy_set_queue((struct wl_proxy *)private_vblank->vblank, NULL);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               wl_tdm_vblank_destroy(private_vblank->vblank);
+               free(private_vblank);
+               if (error)
+                       *error = TDM_ERROR_PROTOCOL_ERROR;
+               pthread_mutex_unlock(&private_client->lock);
+               return NULL;
+       }
+
+       LIST_ADDTAIL(&private_vblank->link, &private_output->vblank_list);
+
        pthread_mutex_unlock(&private_client->lock);
 
        return (tdm_client_vblank*)private_vblank;
@@ -982,6 +1094,11 @@ tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (!name)
                name = TDM_VBLANK_DEFAULT_NAME;
 
@@ -1027,6 +1144,11 @@ tdm_client_vblank_set_fps(tdm_client_vblank *vblank, unsigned int fps)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (private_vblank->fps == fps) {
                pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_NONE;
@@ -1056,6 +1178,11 @@ tdm_client_vblank_set_offset(tdm_client_vblank *vblank, int offset_ms)
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (private_vblank->offset == offset_ms) {
                pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_NONE;
@@ -1083,6 +1210,11 @@ tdm_client_vblank_set_enable_fake(tdm_client_vblank *vblank, unsigned int enable
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (private_vblank->enable_fake == enable_fake) {
                pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_NONE;
@@ -1122,6 +1254,11 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (!private_vblank->started)
                private_vblank->started = 1;
 
@@ -1196,6 +1333,11 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli
        LIST_DEL(&w->link);
        free(w);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        pthread_mutex_unlock(&private_client->lock);
 
        return TDM_ERROR_NONE;
@@ -1224,6 +1366,11 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
 
        pthread_mutex_lock(&private_client->lock);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        if (!private_vblank->started)
                private_vblank->started = 1;
 
@@ -1298,6 +1445,11 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
        LIST_DEL(&w->link);
        free(w);
 
+       if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_PROTOCOL_ERROR;
+       }
+
        pthread_mutex_unlock(&private_client->lock);
 
        return TDM_ERROR_NONE;
index dd01247..4c264ed 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_PROTOCOL_ERROR        = -12, /**< protocol error */
 } tdm_error;
 
 /**
index 0cafffe..e75220c 100644 (file)
@@ -169,6 +169,7 @@ static struct tdm_type_name tdm_error_names[] = {
        { TDM_ERROR_NO_CAPABILITY, "no capability" },
        { TDM_ERROR_DPMS_OFF, "dpms off" },
        { TDM_ERROR_OUTPUT_DISCONNECTED, "output disconnected" },
+       { TDM_ERROR_PROTOCOL_ERROR, "protocol error" },
 };
 TDM_TYPE_NAME_FN(error)