From 45a49594922e43688725291a2812bc85d8eacf1d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 08:30:24 +0900 Subject: [PATCH 01/16] vblank: offset should be greater than 0 Change-Id: Iee03c0b17b51f8a35c844b5d4f6581ada167d8eb --- src/tdm_vblank.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 0362d4e..bdcad07 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -980,6 +980,7 @@ tdm_vblank_set_offset(tdm_vblank *vblank, int offset) tdm_private_vblank *private_vblank = vblank; TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(offset >= 0, TDM_ERROR_INVALID_PARAMETER); if (private_vblank->offset == offset) return TDM_ERROR_NONE; -- 2.7.4 From e35043ff090352d36288507768d0b981e42c2b49 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 07:55:23 +0900 Subject: [PATCH 02/16] output: update caps only in case of changing status between connection and disconnection Change-Id: I63126a368331b494b3a4aa9c17a7e2abbc75a058 --- src/tdm.c | 74 +++++++++++++++++++------------------------------------ src/tdm_output.c | 27 +++++++++----------- src/tdm_private.h | 2 +- 3 files changed, 37 insertions(+), 66 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 3a0ecad..6b796ea 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -375,32 +375,27 @@ _tdm_display_update_layer(tdm_private_output *private_output, TDM_RETURN_VAL_IF_FAIL(private_layer != NULL, TDM_ERROR_OUT_OF_MEMORY); LIST_ADDTAIL(&private_layer->link, &private_output->layer_list); + LIST_INITHEAD(&private_layer->capture_list); + private_layer->index = index; private_layer->private_backend = private_output->private_backend; private_layer->private_display = private_output->private_display; private_layer->private_output = private_output; private_layer->layer_backend = layer_backend; - - LIST_INITHEAD(&private_layer->capture_list); - private_layer->usable = 1; - } else - _tdm_display_destroy_caps_layer(&private_layer->caps); + } - ret = _tdm_display_update_caps_layer(private_layer->private_backend, layer_backend, - &private_layer->caps); - if (ret != TDM_ERROR_NONE) - goto failed_update; + _tdm_display_destroy_caps_layer(&private_layer->caps); + + ret = _tdm_display_update_caps_layer(private_output->private_backend, layer_backend, &private_layer->caps); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); return TDM_ERROR_NONE; -failed_update: - _tdm_display_destroy_private_layer(private_layer); - return ret; } INTERN tdm_error tdm_display_update_output(tdm_private_backend *private_backend, - tdm_output *output_backend, int pipe) + tdm_output *output_backend, int pipe, unsigned int need_new_caps) { tdm_func_output *func_output = &private_backend->func_output; tdm_private_output *private_output = NULL; @@ -441,54 +436,35 @@ tdm_display_update_output(tdm_private_backend *private_backend, private_output); private_output->regist_change_cb = 1; } + } - ret = _tdm_display_update_caps_output(private_backend, pipe, output_backend, - &private_output->caps); - if (ret != TDM_ERROR_NONE) - return ret; - } else { - tdm_caps_output new_caps; - - ret = _tdm_display_update_caps_output(private_backend, pipe, output_backend, - &new_caps); - if (ret != TDM_ERROR_NONE) - return ret; + /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" + * because we have to get new modes. + */ + if (need_new_caps) { + _tdm_display_destroy_caps_output(&private_output->caps); - /* FIXME: This is very ugly. need to fix after the TDM ABI is changed. */ - if (private_output->caps.status != new_caps.status) { - _tdm_display_destroy_caps_output(&private_output->caps); - private_output->caps = new_caps; - private_output->current_mode = NULL; - } else { - tdm_output_mode *old_modes = private_output->caps.modes; - unsigned int old_mode_count = private_output->caps.mode_count; - if (new_caps.modes) - free(new_caps.modes); - new_caps.modes = old_modes; - new_caps.mode_count = old_mode_count; - if (private_output->caps.props) - free(private_output->caps.props); - private_output->caps = new_caps; - } + ret = _tdm_display_update_caps_output(private_backend, pipe, output_backend, &private_output->caps); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); } layers = func_output->output_get_layers(output_backend, &layer_count, &ret); - if (ret != TDM_ERROR_NONE) - goto failed_update; + if (ret != TDM_ERROR_NONE) { + free(layers); + return ret; + } for (i = 0; i < layer_count; i++) { ret = _tdm_display_update_layer(private_output, layers[i], i); - if (ret != TDM_ERROR_NONE) - goto failed_update; + if (ret != TDM_ERROR_NONE) { + free(layers); + return ret; + } } free(layers); return TDM_ERROR_NONE; -failed_update: - _tdm_display_destroy_private_output(private_output); - free(layers); - return ret; } static tdm_output ** @@ -657,7 +633,7 @@ _tdm_display_update(tdm_private_display *private_display) goto failed_update; for (i = 0; i < output_count; i++) { - ret = tdm_display_update_output(private_backend, outputs[i], index++); + ret = tdm_display_update_output(private_backend, outputs[i], index++, 1); if (ret != TDM_ERROR_NONE) goto failed_update; } diff --git a/src/tdm_output.c b/src/tdm_output.c index ed860d3..115cb9d 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -222,20 +222,6 @@ tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status) return ret; } -/* LCOV_EXCL_START */ -static void -_tdm_output_update(tdm_output *output_backend, void *user_data) -{ - tdm_private_output *private_output = user_data; - tdm_error ret; - - TDM_RETURN_IF_FAIL(private_output); - - ret = tdm_display_update_output(private_output->private_backend, output_backend, private_output->pipe); - TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); -} -/* LCOV_EXCL_STOP */ - INTERN void tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { @@ -280,9 +266,17 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, tdm_value value; tdm_error ret; - TDM_INFO("output(%d) main %s", private_output->pipe, tdm_status_str(status)); + TDM_RETURN_IF_FAIL(private_output); - _tdm_output_update(output_backend, user_data); + TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(status)); + + if ((private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED && status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) || + (private_output->caps.status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED && status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)) { + ret = tdm_display_update_output(private_output->private_backend, output_backend, private_output->pipe, 1); + TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + } else { + private_output->caps.status = status; + } value.u32 = status; @@ -954,6 +948,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vblank_handler func, void *user_data) { OUTPUT_FUNC_ENTRY(); + TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); diff --git a/src/tdm_private.h b/src/tdm_private.h index 45b1bab..458ae3c 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -229,7 +229,7 @@ extern char *tdm_debug_dump_dir; tdm_error tdm_display_update_output(tdm_private_backend *private_backend, - tdm_output *output_backend, int pipe); + tdm_output *output_backend, int pipe, unsigned int need_new_caps); tdm_error tdm_display_enable_debug_module(const char*modules); tdm_error -- 2.7.4 From ddc5e40bc89957ccc2badfdc20d09149999418c2 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 09:16:53 +0900 Subject: [PATCH 03/16] client: fix deadlock issue tdmp_vblank shouldn't be protected by mutex. Change-Id: I9bf718402774d3109b0482c2e8f80c4baeee8c54 --- client/tdm_client.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 9d00023..41a5fe2 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -487,8 +487,11 @@ tdm_client_destroy(tdm_client *client) pthread_mutex_lock(&private_client->lock); - if (private_client->temp_vblank) + if (private_client->temp_vblank) { + pthread_mutex_unlock(&private_client->lock); tdm_client_vblank_destroy(private_client->temp_vblank); + pthread_mutex_lock(&private_client->lock); + } LIST_FOR_EACH_ENTRY_SAFE(o, oo, &private_client->output_list, link) { _tdm_client_output_destroy(o); @@ -578,20 +581,12 @@ _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) { - pthread_mutex_unlock(&private_client->lock); + if (vblank_temp->func) vblank_temp->func(sequence, tv_sec, tv_usec, vblank_temp->user_data); - pthread_mutex_lock(&private_client->lock); - } free(vblank_temp); } -- 2.7.4 From 28a7370459ed94026c4bf8e5315deda192aac089 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 11:15:24 +0900 Subject: [PATCH 04/16] client: not allow adding handler twicenot allow Change-Id: Ibc42a95295638ccc87aba5eb6999ef73664be7b2 --- client/tdm_client.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index 41a5fe2..468d984 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -751,6 +751,13 @@ tdm_client_output_add_change_handler(tdm_client_output *output, private_output = (tdm_private_client_output*)output; private_client = private_output->private_client; + LIST_FOR_EACH_ENTRY(h, &private_output->change_handler_list, link) { + if (h->func == func && h->user_data == user_data) { + TDM_ERR("can't add twice"); + return TDM_ERROR_BAD_REQUEST; + } + } + h = calloc(1, sizeof *h); TDM_RETURN_VAL_IF_FAIL(h != NULL, TDM_ERROR_OUT_OF_MEMORY); -- 2.7.4 From 44cf1ade9010917c2ec4ead3a950988f269d4478 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 11:15:38 +0900 Subject: [PATCH 05/16] client: check invalid params Change-Id: I637a30bb799589d359c8e9bfdafdec539a062717 --- client/tdm_client.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 468d984..a665eb1 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -659,8 +659,14 @@ tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) return NULL; } - if (!name) + if (!name) { name = "primary"; + } else if (strncmp(name, "primary", 7) && strncmp(name, "default", 7)) { + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + pthread_mutex_unlock(&private_client->lock); + return NULL; + } LIST_FOR_EACH_ENTRY(private_output, &private_client->output_list, link) { if (!strncmp(private_output->name, name, TDM_NAME_LEN)) { -- 2.7.4 From 30ec37847bd0e9090f8f2e21f8980bebed4d5ee9 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:31:36 +0900 Subject: [PATCH 06/16] client: no need to check watch_output_changes 1) If watch_output_changes == true, private_output->dpms has been already updated in _tdm_client_output_cb_dpms. 2) If watch_output_changes == false, server will return TDM_ERROR_DPMS_OFF. The dpms value in client side is not important. If a client calls tdm_client_output_get_dpms, private_output->dpms will be updated. Change-Id: I6d6ea1df74955c44ce02c2d7a39aa589d38ba516 --- client/tdm_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index a665eb1..a257939 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -1270,7 +1270,7 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli if (!private_vblank->started) private_vblank->started = 1; - if (private_output->watch_output_changes && !private_vblank->enable_fake) { + if (!private_vblank->enable_fake) { if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { TDM_ERR("output disconnected"); pthread_mutex_unlock(&private_client->lock); @@ -1382,7 +1382,7 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, if (!private_vblank->started) private_vblank->started = 1; - if (private_output->watch_output_changes && !private_vblank->enable_fake) { + if (!private_vblank->enable_fake) { if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { TDM_ERR("output disconnected"); pthread_mutex_unlock(&private_client->lock); -- 2.7.4 From 2d31ca4382bc1bf50e8ecfbf657a26762609f010 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:32:49 +0900 Subject: [PATCH 07/16] client: let a server know the watch status Change-Id: I25652d7f92bb47909ef3d3873ee0df2620261d1f --- client/tdm_client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index a257939..460cda4 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -777,6 +777,7 @@ tdm_client_output_add_change_handler(tdm_client_output *output, if (LIST_IS_EMPTY(&private_output->change_handler_list)) { wl_tdm_output_watch_output_changes(private_output->output, 1); + wl_display_roundtrip_queue(private_client->display, private_client->queue); /* TODO: this is very tricky. * If a client adds the change_handler, we might be able to guess that @@ -823,8 +824,10 @@ tdm_client_output_remove_change_handler(tdm_client_output *output, free(h); if (LIST_IS_EMPTY(&private_output->change_handler_list)) { - if (!CHECK_WL_PROTOCOL_ERROR(private_client)) + if (!CHECK_WL_PROTOCOL_ERROR(private_client)) { wl_tdm_output_watch_output_changes(private_output->output, 0); + wl_display_roundtrip_queue(private_client->display, private_client->queue); + } } pthread_mutex_unlock(&private_client->lock); -- 2.7.4 From 51eb6acc7af0c288896dc1a10d7577cfd8459bc8 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:33:21 +0900 Subject: [PATCH 08/16] display: add tdm_display_flush Change-Id: I8fd5bf404cac29d323a858bec482e45754d7ef9d --- include/tdm.h | 7 +++++++ src/tdm_display.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 9ae31a3..09a0f7b 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -96,6 +96,13 @@ tdm_error tdm_display_handle_events(tdm_display *dpy); /** + * @brief Flush the all events to clients + * @param[in] dpy A display object + */ +void +tdm_display_flush(tdm_display *dpy); + +/** * @brief Get the capabilities of a display object. * @details A frontend user can get whether TDM supports pp/capture functionality with this function. * @param[in] dpy A display object diff --git a/src/tdm_display.c b/src/tdm_display.c index a7e880e..d2fba50 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -405,6 +405,20 @@ tdm_display_handle_events(tdm_display *dpy) return ret; } +EXTERN void +tdm_display_flush(tdm_display *dpy) +{ + tdm_private_display *private_display; + + TDM_RETURN_IF_FAIL(dpy != NULL); + private_display = (tdm_private_display*)dpy; + + if (tdm_thread_is_running()) + return; + + tdm_event_loop_flush(private_display); +} + EXTERN tdm_error tdm_display_get_backend_info(tdm_display *dpy, const char **name, const char **vendor, int *major, int *minor) -- 2.7.4 From 84359b1a8fff55688fd9a7951f2ab38ffa702b75 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:35:34 +0900 Subject: [PATCH 09/16] display: add tdm_display_find_output Change-Id: I78c86c27e3f6c8c0cbf31d04455c3024d936e9a5 --- include/tdm.h | 10 ++++++++++ src/tdm_display.c | 31 +++++++++++++++++++++++++++++++ src/tdm_server.c | 41 +---------------------------------------- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 09a0f7b..7d8ed4d 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -207,6 +207,16 @@ tdm_output * tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error); /** + * @brief Find a output object which has the given name. + * @param[in] dpy A display object + * @param[in] name The name of a output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A output object if success. Otherwise, NULL. + */ +tdm_output * +tdm_display_find_output(tdm_display *dpy, const char *name, tdm_error *error); + +/** * @brief Create a pp object. * @param[in] dpy A display object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/src/tdm_display.c b/src/tdm_display.c index d2fba50..cd6e81e 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -343,6 +343,37 @@ tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error) return NULL; } +EXTERN tdm_output * +tdm_display_find_output(tdm_display *dpy, const char *name, tdm_error *error) +{ + tdm_private_backend *private_backend = NULL; + tdm_private_output *private_output = NULL; + + DISPLAY_FUNC_ENTRY_ERROR(); + + if (!strncasecmp(name, "primary", 7) || !strncasecmp(name, "default", 7)) { + return tdm_display_get_output(dpy, 0, error); + } + + _pthread_mutex_lock(&private_display->lock); + + if (error) + *error = TDM_ERROR_NONE; + + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + if (strncmp(private_output->caps.model, name, TDM_NAME_LEN)) + continue; + _pthread_mutex_unlock(&private_display->lock); + return private_output; + } + } + + _pthread_mutex_unlock(&private_display->lock); + + return NULL; +} + EXTERN tdm_error tdm_display_get_fd(tdm_display *dpy, int *fd) { diff --git a/src/tdm_server.c b/src/tdm_server.c index 1bb5683..968a6ed 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -121,45 +121,6 @@ _tdm_server_get_process_name(pid_t pid, char *name, unsigned int size) fclose(h); } -static tdm_output* -_tdm_server_find_output(tdm_private_server *private_server, const char *name) -{ - tdm_private_loop *private_loop = private_server->private_loop; - tdm_output *found = NULL; - - if (!strncasecmp(name, "primary", 7) || !strncasecmp(name, "default", 7)) - found = tdm_display_get_output(private_loop->dpy, 0, NULL); - - if (!found) { - int count = 0, i; - - tdm_display_get_output_count(private_loop->dpy, &count); - - for (i = 0; i < count; i++) { - tdm_output *output = tdm_display_get_output(private_loop->dpy, i, NULL); - tdm_output_conn_status status; - const char *model = NULL; - tdm_error ret; - - ret = tdm_output_get_conn_status(output, &status); - if (ret || status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) - continue; - - ret = tdm_output_get_model_info(output, NULL, &model, NULL); - if (ret || !model) - continue; - - if (strncmp(model, name, TDM_NAME_LEN)) - continue; - - found = output; - break; - } - } - - return found; -} - /* LCOV_EXCL_START */ static void _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, @@ -636,7 +597,7 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; tdm_error ret; - output = _tdm_server_find_output(private_server, name); + output = tdm_display_find_output(private_server->private_loop->dpy, name, NULL); if (!output) { /* LCOV_EXCL_START */ -- 2.7.4 From 939ced9e20983ce7d8ad80cb075e1c4ac80d392e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:34:46 +0900 Subject: [PATCH 10/16] output: correct syntax error Change-Id: I3fd9c71554093877da1e975ce4b870a9cb9a5497 --- src/tdm_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 115cb9d..2e3cfce 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -316,7 +316,7 @@ tdm_output_add_change_handler(tdm_output *output, _pthread_mutex_lock(&private_display->lock); LIST_FOR_EACH_ENTRY(change_handler, &private_output->change_handler_list, link) { - if (change_handler->func == func || change_handler->user_data == user_data) { + if (change_handler->func == func && change_handler->user_data == user_data) { TDM_ERR("can't add twice"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_BAD_REQUEST; -- 2.7.4 From 278ae74126ba11c906c1780f303b3245148de555 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:35:53 +0900 Subject: [PATCH 11/16] server: correct syntax error Change-Id: I1fa8fa63a4acda61638a2a94b2e9023a6c75ef47 --- src/tdm_server.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tdm_server.c b/src/tdm_server.c index 968a6ed..840e575 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -486,7 +486,7 @@ _tdm_server_output_cb_get_connection(struct wl_client *client, struct wl_resourc TDM_RETURN_IF_FAIL(output_info != NULL); ret = tdm_output_get_conn_status(output_info->output, &status); - TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed); wl_tdm_output_send_connection(output_info->resource, status, ret); @@ -506,14 +506,14 @@ _tdm_server_output_cb_get_mode(struct wl_client *client, struct wl_resource *res TDM_RETURN_IF_FAIL(output_info != NULL); ret = tdm_output_get_conn_status(output_info->output, &status); - TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed); if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { const tdm_output_mode *mode = NULL; unsigned int hdisplay, vdisplay, vrefresh; ret = tdm_output_get_mode(output_info->output, &mode); - TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed); hdisplay = (mode) ? mode->hdisplay : 0; vdisplay = (mode) ? mode->vdisplay : 0; @@ -539,13 +539,13 @@ _tdm_server_output_cb_get_dpms(struct wl_client *client, struct wl_resource *res TDM_RETURN_IF_FAIL(output_info != NULL); ret = tdm_output_get_conn_status(output_info->output, &status); - TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed); if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { tdm_output_dpms dpms_value = TDM_OUTPUT_DPMS_OFF; ret = tdm_output_get_dpms(output_info->output, &dpms_value); - TDM_GOTO_IF_FAIL(ret != TDM_ERROR_NONE, failed); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed); wl_tdm_output_send_dpms(output_info->resource, dpms_value, ret); } else { -- 2.7.4 From 45c4c5c6af9816df36118a51341e3d0a618c0a6e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:36:14 +0900 Subject: [PATCH 12/16] server: check return value Change-Id: I6efd4944ec752d7b9ce70ed67a2ef73021b1f1f1 --- src/tdm_server.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tdm_server.c b/src/tdm_server.c index 840e575..f5e222a 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -634,14 +634,21 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou /* LCOV_EXCL_STOP */ } + ret = tdm_output_add_change_handler(output, _tdm_server_cb_output_change, output_info); + if (ret != TDM_ERROR_NONE) { + wl_resource_post_no_memory(resource); + wl_resource_destroy(output_resource); + free(output_info); + TDM_ERR("tdm_output_add_change_handler failed"); + return; + } + LIST_ADDTAIL(&output_info->link, &private_server->output_list); output_info->private_server = private_server; output_info->resource = output_resource; output_info->output = output; LIST_INITHEAD(&output_info->vblank_list); - tdm_output_add_change_handler(output, _tdm_server_cb_output_change, output_info); - wl_resource_set_implementation(output_resource, &tdm_output_implementation, output_info, destroy_output_callback); -- 2.7.4 From 5d2ab50d17d3c9ca3efefb4373441c8faf23cba4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:36:25 +0900 Subject: [PATCH 13/16] vblank: check return value Change-Id: Iafc93e27e3d9b41c2a2ca61c1da9622f9a8b27d8 --- src/tdm_vblank.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index bdcad07..6db4ac7 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -744,7 +744,14 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) /* LCOV_EXCL_STOP */ } - tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank); + ret = tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank); + if (ret != TDM_ERROR_NONE) { + free(private_vblank); + if (error) + *error = TDM_ERROR_OPERATION_FAILED; + TDM_ERR("tdm_output_add_change_handler failed"); + return NULL; + } private_vblank->stamp = ++stamp; private_vblank->owner_tid = syscall(SYS_gettid); -- 2.7.4 From 20a81eedd3756b10a5190b0c158aac753f8dc32e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 15:38:41 +0900 Subject: [PATCH 14/16] thread: fix deadlock issue when there are callbacks in cb_list[0] and cb_list[1], display-thread and tdm- thread are slept in pthread_cond_wait. Change-Id: If5d459b5f8579fcbf05765de12f76cca548de6eb --- src/tdm_thread.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 3811bdc..38a76a4 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -610,6 +610,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) pid_t caller_tid; struct list_head *list, *other_list; struct list_head call_list; + static pid_t waiting_tid = 0; tdm_error ret; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -667,19 +668,22 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) assert(LIST_IS_EMPTY(&call_list)); - LIST_FOR_EACH_ENTRY_SAFE(cb, hh, other_list, link) { - if (cb->object != object || - cb->cb_type != cb_base->type || - cb->cb_data != cb_base->data) - continue; + if (waiting_tid == 0) { + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, other_list, link) { + if (cb->object != object || + cb->cb_type != cb_base->type || + cb->cb_data != cb_base->data) + continue; - handler_in_other_thread = 1; - break; + handler_in_other_thread = 1; + break; + } } if (!handler_in_other_thread) { if (keep_private_thread) { if (cb_base->sync) { + waiting_tid = 0; pthread_cond_signal(&keep_private_thread->event_cond); if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("pthread broadcase"); @@ -705,6 +709,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) * the mutex shall have been locked and shall be owned by the calling thread */ tdm_mutex_locked = 0; + waiting_tid = caller_tid; pthread_cond_wait(&keep_private_thread->event_cond, &private_display->lock); tdm_mutex_locked = 1; } -- 2.7.4 From d1d8e93edf9704796d42154c2b02e515820cabcc Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Feb 2018 16:23:48 +0900 Subject: [PATCH 15/16] vblank: ignore global fps for server's vblank Change-Id: I4188bd1e539792f3a2fbb6547d39276581175896 --- src/tdm_vblank.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 6db4ac7..dddb423 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -1542,7 +1542,8 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, wait_info->user_data = user_data; wait_info->private_vblank = private_vblank; - if (private_vblank->ignore_global_fps || + if (!private_vblank->resource || + private_vblank->ignore_global_fps || vblank_global_fps == 0 || private_vblank->fps < vblank_global_fps) fps = private_vblank->fps; -- 2.7.4 From 3d9d95629a181070f3d8ef8e5e5103f4c7045e9d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 27 Feb 2018 08:29:23 +0900 Subject: [PATCH 16/16] client: initializing pointer Change-Id: I36f67b911a8335766fa9d3b0385ec4e6aef0e720 --- client/tdm_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 460cda4..4c38190 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -749,7 +749,7 @@ tdm_client_output_add_change_handler(tdm_client_output *output, { tdm_private_client_output *private_output; tdm_private_client *private_client; - tdm_client_output_handler_info *h; + tdm_client_output_handler_info *h = NULL; TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); -- 2.7.4