From 10de61c4b401e727f63bc3fbc965ccd0bc0304ae Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 30 Jan 2018 10:35:36 +0900 Subject: [PATCH] client: add mutex lock Change-Id: I2c2cb6f7a06b67dcacfd6e1bcf502877ead20dc5 --- client/tdm_client.c | 246 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 208 insertions(+), 38 deletions(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 81806d4..51e5c5e 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -55,6 +55,8 @@ typedef struct _tdm_private_client_vblank tdm_private_client_vblank; typedef struct _tdm_private_client { + pthread_mutex_t lock; + struct wl_display *display; struct wl_event_queue *queue; struct wl_registry *registry; @@ -115,6 +117,7 @@ typedef struct _tdm_client_output_handler_info { void *user_data; struct list_head link; + struct list_head call_link; } tdm_client_output_handler_info; typedef struct _tdm_client_wait_info { @@ -128,6 +131,7 @@ typedef struct _tdm_client_wait_info { int need_free; struct list_head link; + struct list_head call_link; } tdm_client_wait_info; static void @@ -153,35 +157,50 @@ _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uint32_t tv_usec, uint32_t error) { tdm_private_client_vblank *private_vblank = data; - tdm_client_wait_info *w = NULL, *ww = NULL; + tdm_private_client *private_client; + tdm_client_wait_info *w = NULL, *wait_info = NULL; TDM_RETURN_IF_FAIL(private_vblank != NULL); + private_client = private_vblank->private_output->private_client; + private_vblank->last_time = TDM_TIME(tv_sec, tv_usec); TDM_DBG("vblank(%p) req_id(%u) sequence(%u) time(%.6f)", private_vblank, req_id, sequence, TDM_TIME(tv_sec, tv_usec)); - LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->wait_list, link) { + LIST_FOR_EACH_ENTRY(w, &private_vblank->wait_list, link) { if (w->req_id != req_id) continue; - if (private_vblank->enable_ttrace) - TDM_TRACE_ASYNC_END((int)w->req_time, "TDM_Client_Vblank:%u", private_vblank->stamp); + wait_info = w; + break; + } + + if (!wait_info) { + TDM_ERR("no wait infomation for req_id(%d)", req_id); + return; + } - if (w->req_time >= private_vblank->last_time) - TDM_WRN("'req(%.6f) < last(%.6f)' failed", w->req_time, private_vblank->last_time); + if (private_vblank->enable_ttrace) + TDM_TRACE_ASYNC_END((int)wait_info->req_time, "TDM_Client_Vblank:%u", private_vblank->stamp); - if (w->func) - w->func(private_vblank, error, sequence, tv_sec, tv_usec, w->user_data); + if (wait_info->req_time >= private_vblank->last_time) + TDM_WRN("'req(%.6f) < last(%.6f)' failed. error(%d)", wait_info->req_time, private_vblank->last_time, error); - if (w->need_free) { - LIST_DEL(&w->link); - free(w); - } else - w->need_free = 1; - return; + if (wait_info->need_free) + LIST_DEL(&wait_info->link); + + if (wait_info->func) { + pthread_mutex_unlock(&private_client->lock); + wait_info->func(private_vblank, error, sequence, tv_sec, tv_usec, wait_info->user_data); + pthread_mutex_lock(&private_client->lock); } + + if (wait_info->need_free) + free(w); + else + wait_info->need_free = 1; } /* LCOV_EXCL_STOP */ @@ -257,11 +276,15 @@ static void _tdm_client_output_cb_connection(void *data, struct wl_tdm_output *wl_tdm_output, uint32_t value, uint32_t error) { tdm_private_client_output *private_output = (tdm_private_client_output*)data; - tdm_client_output_handler_info *h = NULL; + tdm_private_client *private_client; + tdm_client_output_handler_info *h = NULL, *hh = NULL; tdm_value v; + struct list_head call_list; TDM_RETURN_IF_FAIL(private_output != NULL); + private_client = private_output->private_client; + if (private_output->connection == value) return; @@ -275,22 +298,34 @@ _tdm_client_output_cb_connection(void *data, struct wl_tdm_output *wl_tdm_output wl_proxy_get_id((struct wl_proxy*)private_output->output), value); - v.u32 = value; + LIST_INITHEAD(&call_list); + LIST_FOR_EACH_ENTRY(h, &private_output->change_handler_list, link) { + LIST_ADDTAIL(&h->call_link, &call_list); + } + + v.u32 = value; + pthread_mutex_unlock(&private_client->lock); + LIST_FOR_EACH_ENTRY_SAFE(h, hh, &call_list, call_link) { if (h->func) h->func(private_output, TDM_OUTPUT_CHANGE_CONNECTION, v, h->user_data); } + pthread_mutex_lock(&private_client->lock); } static void _tdm_client_output_cb_dpms(void *data, struct wl_tdm_output *wl_tdm_output, uint32_t value, uint32_t error) { tdm_private_client_output *private_output = (tdm_private_client_output*)data; - tdm_client_output_handler_info *h = NULL; + tdm_private_client *private_client; + tdm_client_output_handler_info *h = NULL, *hh = NULL; tdm_value v; + struct list_head call_list; TDM_RETURN_IF_FAIL(private_output != NULL); + private_client = private_output->private_client; + /* If value is extended value, we handle it as DPMS on in client side * The extended DPMS value is valid only in server side. * Or, need to export to client side also? @@ -311,11 +346,19 @@ _tdm_client_output_cb_dpms(void *data, struct wl_tdm_output *wl_tdm_output, uint wl_proxy_get_id((struct wl_proxy*)private_output->output), value); - v.u32 = value; + LIST_INITHEAD(&call_list); + LIST_FOR_EACH_ENTRY(h, &private_output->change_handler_list, link) { + LIST_ADDTAIL(&h->call_link, &call_list); + } + + v.u32 = value; + pthread_mutex_unlock(&private_client->lock); + LIST_FOR_EACH_ENTRY_SAFE(h, hh, &call_list, call_link) { if (h->func) h->func(private_output, TDM_OUTPUT_CHANGE_DPMS, v, h->user_data); } + pthread_mutex_lock(&private_client->lock); } static const struct wl_tdm_output_listener tdm_client_output_listener = { @@ -369,6 +412,14 @@ tdm_client_create(tdm_error *error) /* LCOV_EXCL_STOP */ } + if (pthread_mutex_init(&private_client->lock, NULL)) { + TDM_ERR("mutex init failed: %m"); + free(private_client); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + } + LIST_INITHEAD(&private_client->output_list); private_client->display = wl_display_connect("tdm-socket"); @@ -407,6 +458,8 @@ tdm_client_destroy(tdm_client *client) if (!private_client) return; + pthread_mutex_lock(&private_client->lock); + if (private_client->temp_vblank) tdm_client_vblank_destroy(private_client->temp_vblank); @@ -423,6 +476,9 @@ tdm_client_destroy(tdm_client *client) if (private_client->display) wl_display_disconnect(private_client->display); + pthread_mutex_unlock(&private_client->lock); + pthread_mutex_destroy(&private_client->lock); + free(private_client); } @@ -436,7 +492,12 @@ tdm_client_get_fd(tdm_client *client, int *fd) private_client = (tdm_private_client*)client; + pthread_mutex_lock(&private_client->lock); + *fd = wl_display_get_fd(private_client->display); + + pthread_mutex_unlock(&private_client->lock); + if (*fd < 0) return TDM_ERROR_OPERATION_FAILED; @@ -453,6 +514,8 @@ tdm_client_handle_events(tdm_client *client) /* LCOV_EXCL_START */ private_client = (tdm_private_client*)client; + pthread_mutex_lock(&private_client->lock); + if (private_client->enable_ttrace) TDM_TRACE_ASYNC_BEGIN((int)private_client->stamp, "TDM_Client_Events:%u", (unsigned int)private_client->stamp); @@ -461,6 +524,8 @@ 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); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; /* LCOV_EXCL_STOP */ } @@ -476,11 +541,20 @@ _tdm_client_vblank_handler_temp(tdm_client_vblank *vblank, tdm_error error, unsi unsigned int tv_sec, unsigned int tv_usec, void *user_data) { tdm_client_vblank_temp *vblank_temp = user_data; + tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_IF_FAIL(vblank_temp != NULL); + TDM_RETURN_IF_FAIL(vblank != NULL); + + private_vblank = vblank; + private_client = private_vblank->private_output->private_client; - if (vblank_temp->func) + if (vblank_temp->func) { + pthread_mutex_unlock(&private_client->lock); vblank_temp->func(sequence, tv_sec, tv_usec, vblank_temp->user_data); + pthread_mutex_lock(&private_client->lock); + } free(vblank_temp); } @@ -541,12 +615,16 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) private_client = (tdm_private_client*)client; + pthread_mutex_lock(&private_client->lock); + if (!name) name = "primary"; LIST_FOR_EACH_ENTRY(private_output, &private_client->output_list, link) { - if (!strncmp(private_output->name, name, TDM_NAME_LEN)) + if (!strncmp(private_output->name, name, TDM_NAME_LEN)) { + pthread_mutex_unlock(&private_client->lock); return (tdm_client_output*)private_output; + } } wrapper = wl_proxy_create_wrapper(private_client->tdm); @@ -554,6 +632,7 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) TDM_ERR("create output_wrapper failed"); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; } @@ -566,6 +645,7 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) TDM_ERR("alloc failed"); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; /* LCOV_EXCL_STOP */ @@ -583,6 +663,7 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) free(private_output); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; /* LCOV_EXCL_STOP */ @@ -598,6 +679,8 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) wl_proxy_set_queue((struct wl_proxy *)private_output->output, NULL); + pthread_mutex_unlock(&private_client->lock); + return (tdm_client_output*)private_output; } @@ -607,16 +690,20 @@ tdm_client_output_add_change_handler(tdm_client_output *output, void *user_data) { tdm_private_client_output *private_output; + tdm_private_client *private_client; tdm_client_output_handler_info *h; TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; h = calloc(1, sizeof *h); TDM_RETURN_VAL_IF_FAIL(h != NULL, TDM_ERROR_OUT_OF_MEMORY); + pthread_mutex_lock(&private_client->lock); + if (LIST_IS_EMPTY(&private_output->change_handler_list)) { wl_tdm_output_watch_output_changes(private_output->output, 1); @@ -633,8 +720,11 @@ tdm_client_output_add_change_handler(tdm_client_output *output, h->func = func; h->user_data = user_data; LIST_ADDTAIL(&h->link, &private_output->change_handler_list); + LIST_INITHEAD(&h->call_link); + + pthread_mutex_unlock(&private_client->lock); - return TDM_ERROR_NOT_IMPLEMENTED; + return TDM_ERROR_NONE; } void @@ -643,12 +733,16 @@ tdm_client_output_remove_change_handler(tdm_client_output *output, void *user_data) { tdm_private_client_output *private_output; + tdm_private_client *private_client; tdm_client_output_handler_info *h = NULL; TDM_RETURN_IF_FAIL(output != NULL); TDM_RETURN_IF_FAIL(func != NULL); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; + + pthread_mutex_lock(&private_client->lock); LIST_FOR_EACH_ENTRY(h, &private_output->change_handler_list, link) { if (h->func != func || h->user_data != user_data) @@ -660,8 +754,12 @@ tdm_client_output_remove_change_handler(tdm_client_output *output, if (LIST_IS_EMPTY(&private_output->change_handler_list)) wl_tdm_output_watch_output_changes(private_output->output, 0); + pthread_mutex_unlock(&private_client->lock); + return; } + + pthread_mutex_unlock(&private_client->lock); } tdm_error @@ -674,15 +772,16 @@ tdm_client_output_get_refresh_rate(tdm_client_output *output, unsigned int *refr TDM_RETURN_VAL_IF_FAIL(refresh != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; + + pthread_mutex_lock(&private_client->lock); if (private_output->watch_output_changes) { *refresh = private_output->refresh; + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; } - private_client = private_output->private_client; - TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); - 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); @@ -690,6 +789,8 @@ tdm_client_output_get_refresh_rate(tdm_client_output *output, unsigned int *refr *refresh = private_output->refresh; + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -703,15 +804,16 @@ tdm_client_output_get_conn_status(tdm_client_output *output, tdm_output_conn_sta TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; + + pthread_mutex_lock(&private_client->lock); if (private_output->watch_output_changes) { *status = private_output->connection; + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; } - private_client = private_output->private_client; - TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); - 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); @@ -719,6 +821,8 @@ tdm_client_output_get_conn_status(tdm_client_output *output, tdm_output_conn_sta *status = private_output->connection; + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -732,14 +836,14 @@ tdm_client_output_get_dpms(tdm_client_output *output, tdm_output_dpms *dpms) TDM_RETURN_VAL_IF_FAIL(dpms != NULL, TDM_ERROR_INVALID_PARAMETER); private_output = (tdm_private_client_output*)output; + private_client = private_output->private_client; if (private_output->watch_output_changes) { *dpms = private_output->dpms; return TDM_ERROR_NONE; } - private_client = private_output->private_client; - TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); + pthread_mutex_lock(&private_client->lock); wl_proxy_set_queue((struct wl_proxy *)private_output->output, private_client->queue); wl_tdm_output_get_dpms(private_output->output); @@ -748,6 +852,8 @@ tdm_client_output_get_dpms(tdm_client_output *output, tdm_output_dpms *dpms) *dpms = private_output->dpms; + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -772,18 +878,14 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error) private_output = (tdm_private_client_output*)output; private_client = private_output->private_client; - if (!private_client) { - TDM_ERR("'!private_client' failed"); - if (error) - *error = TDM_ERROR_INVALID_PARAMETER; - return NULL; - } + pthread_mutex_lock(&private_client->lock); wrapper = wl_proxy_create_wrapper(private_output->output); if (!wrapper) { TDM_ERR("create output_wrapper failed"); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; } @@ -797,6 +899,7 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error) wl_proxy_wrapper_destroy(wrapper); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; /* LCOV_EXCL_STOP */ @@ -813,6 +916,7 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error) free(private_vblank); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; + pthread_mutex_unlock(&private_client->lock); return NULL; /* LCOV_EXCL_STOP */ @@ -832,6 +936,8 @@ tdm_client_output_create_vblank(tdm_client_output *output, tdm_error *error) wl_proxy_set_queue((struct wl_proxy *)private_vblank->vblank, NULL); + pthread_mutex_unlock(&private_client->lock); + return (tdm_client_vblank*)private_vblank; } @@ -839,11 +945,16 @@ void tdm_client_vblank_destroy(tdm_client_vblank *vblank) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; tdm_client_wait_info *w = NULL, *ww = NULL; TDM_RETURN_IF_FAIL(vblank != NULL); private_vblank = vblank; + private_client = private_vblank->private_output->private_client; + + pthread_mutex_lock(&private_client->lock); + LIST_DEL(&private_vblank->link); LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->wait_list, link) { @@ -854,16 +965,22 @@ tdm_client_vblank_destroy(tdm_client_vblank *vblank) wl_tdm_vblank_destroy(private_vblank->vblank); free(private_vblank); + + pthread_mutex_unlock(&private_client->lock); } tdm_error tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; + private_client = private_vblank->private_output->private_client; + + pthread_mutex_lock(&private_client->lock); if (!name) name = TDM_VBLANK_DEFAULT_NAME; @@ -873,6 +990,8 @@ tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name) wl_tdm_vblank_set_name(private_vblank->vblank, private_vblank->name); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -880,11 +999,16 @@ tdm_error tdm_client_vblank_set_sync(tdm_client_vblank *vblank, unsigned int sync) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; + private_client = private_vblank->private_output->private_client; + + pthread_mutex_lock(&private_client->lock); private_vblank->sync = sync; + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; } @@ -893,18 +1017,27 @@ tdm_error tdm_client_vblank_set_fps(tdm_client_vblank *vblank, unsigned int fps) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; + private_client = private_vblank->private_output->private_client; - if (private_vblank->fps == fps) + pthread_mutex_lock(&private_client->lock); + + if (private_vblank->fps == fps) { + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; + } + private_vblank->fps = fps; wl_tdm_vblank_set_fps(private_vblank->vblank, fps); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -912,18 +1045,28 @@ tdm_error tdm_client_vblank_set_offset(tdm_client_vblank *vblank, int offset_ms) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; TDM_RETURN_VAL_IF_FAIL(private_vblank->started == 0, TDM_ERROR_BAD_REQUEST); - if (private_vblank->offset == offset_ms) + private_client = private_vblank->private_output->private_client; + + pthread_mutex_lock(&private_client->lock); + + if (private_vblank->offset == offset_ms) { + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; + } + private_vblank->offset = offset_ms; wl_tdm_vblank_set_offset(private_vblank->vblank, offset_ms); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -931,17 +1074,26 @@ tdm_error tdm_client_vblank_set_enable_fake(tdm_client_vblank *vblank, unsigned int enable_fake) { tdm_private_client_vblank *private_vblank; + tdm_private_client *private_client; TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; + private_client = private_vblank->private_output->private_client; + + pthread_mutex_lock(&private_client->lock); - if (private_vblank->enable_fake == enable_fake) + if (private_vblank->enable_fake == enable_fake) { + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; + } + private_vblank->enable_fake = enable_fake; wl_tdm_vblank_set_enable_fake(private_vblank->vblank, enable_fake); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; } @@ -968,16 +1120,20 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli private_output = private_vblank->private_output; private_client = private_output->private_client; + pthread_mutex_lock(&private_client->lock); + if (!private_vblank->started) private_vblank->started = 1; if (private_output->watch_output_changes && !private_vblank->enable_fake) { if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { TDM_ERR("output disconnected"); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_OUTPUT_DISCONNECTED; } if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->dpms)) { TDM_ERR("dpms %s", tdm_dpms_str(private_output->dpms)); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_DPMS_OFF; } } @@ -987,6 +1143,7 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli /* LCOV_EXCL_START */ TDM_ERR("alloc failed"); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_OUT_OF_MEMORY; /* LCOV_EXCL_STOP */ @@ -997,6 +1154,7 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli w->user_data = user_data; LIST_ADDTAIL(&w->link, &private_vblank->wait_list); + LIST_INITHEAD(&w->call_link); clock_gettime(CLOCK_MONOTONIC, &tp); req_sec = (unsigned int)tp.tv_sec; @@ -1021,6 +1179,7 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli if (!private_vblank->sync) { wl_display_flush(private_client->display); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; } @@ -1037,6 +1196,8 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli LIST_DEL(&w->link); free(w); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; /* LCOV_EXCL_STOP */ @@ -1061,16 +1222,20 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, private_output = private_vblank->private_output; private_client = private_output->private_client; + pthread_mutex_lock(&private_client->lock); + if (!private_vblank->started) private_vblank->started = 1; if (private_output->watch_output_changes && !private_vblank->enable_fake) { if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { TDM_ERR("output disconnected"); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_OUTPUT_DISCONNECTED; } if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->dpms)) { TDM_ERR("dpms %s", tdm_dpms_str(private_output->dpms)); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_DPMS_OFF; } } @@ -1080,6 +1245,7 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, /* LCOV_EXCL_START */ TDM_ERR("alloc failed"); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_OUT_OF_MEMORY; /* LCOV_EXCL_STOP */ @@ -1090,6 +1256,7 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, w->user_data = user_data; LIST_ADDTAIL(&w->link, &private_vblank->wait_list); + LIST_INITHEAD(&w->call_link); clock_gettime(CLOCK_MONOTONIC, &tp); req_sec = (unsigned int)tp.tv_sec; @@ -1114,6 +1281,7 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, if (!private_vblank->sync) { wl_display_flush(private_client->display); + pthread_mutex_unlock(&private_client->lock); return TDM_ERROR_NONE; } @@ -1130,6 +1298,8 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, LIST_DEL(&w->link); free(w); + pthread_mutex_unlock(&private_client->lock); + return TDM_ERROR_NONE; /* LCOV_EXCL_STOP */ -- 2.7.4