From 00ea04e4b1be5ea91fa143c44c83311eb3eead64 Mon Sep 17 00:00:00 2001 From: Hideyuki Nagase Date: Tue, 15 Jun 2021 08:50:31 -0700 Subject: [PATCH] fix display loop keep awake --- libweston/backend-rdp/rdp.c | 18 +++++-- libweston/backend-rdp/rdp.h | 28 ++--------- libweston/backend-rdp/rdpclip.c | 86 ++++++++++++++++++++------------- libweston/backend-rdp/rdpdisp.c | 42 ++++++++++------ libweston/backend-rdp/rdprail.c | 52 +++++++++++--------- libweston/backend-rdp/rdputil.c | 34 +++++++++++++ 6 files changed, 161 insertions(+), 99 deletions(-) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index f87815dad..486694dae 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -856,6 +857,8 @@ rdp_peer_context_new(freerdp_peer* client, RdpPeerContext* context) context->item.peer = client; context->item.flags = RDP_PEER_OUTPUT_ENABLED; + context->loop_event_source_fd = -1; + #if FREERDP_VERSION_MAJOR == 1 && FREERDP_VERSION_MINOR == 1 context->rfx_context = rfx_context_new(); #else @@ -901,6 +904,9 @@ rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context) wl_list_remove(&context->item.link); + if (context->loop_event_source_fd != -1) + close(context->loop_event_source_fd); + for (i = 0; i < ARRAY_LENGTH(context->events); i++) { if (context->events[i]) wl_event_source_remove(context->events[i]); @@ -1827,9 +1833,6 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) peerCtx->vcm = WTSOpenServerA((LPSTR)peerCtx); if (peerCtx->vcm) { WTSVirtualChannelManagerGetFileDescriptor(peerCtx->vcm, rfds, &rcount); - peerCtx->eventVcm = WTSVirtualChannelManagerGetEventHandle(peerCtx->vcm); - /* event must be valid when server is successfully opened */ - assert(peerCtx->eventVcm); } else { rdp_debug_error(b, "WTSOpenServer is failed! continue without virtual channel.\n"); } @@ -1844,6 +1847,10 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) for ( ; i < ARRAY_LENGTH(peerCtx->events); i++) peerCtx->events[i] = 0; + peerCtx->loop_event_source_fd = eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC); + if (peerCtx->loop_event_source_fd == -1) + goto error_peer_initialize; + if (!rdp_rail_peer_init(client, peerCtx)) goto error_peer_initialize; @@ -1860,6 +1867,10 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) return 0; error_peer_initialize: + if (peerCtx->loop_event_source_fd != -1) { + close(peerCtx->loop_event_source_fd); + peerCtx->loop_event_source_fd = -1; + } for (i = 0; i < ARRAY_LENGTH(peerCtx->events); i++) { if (peerCtx->events[i]) { wl_event_source_remove(peerCtx->events[i]); @@ -1868,7 +1879,6 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) } if (peerCtx->vcm) { WTSCloseServer(peerCtx->vcm); - peerCtx->eventVcm = NULL; peerCtx->vcm = NULL; } diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index c7320f3d6..b05473b42 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -281,7 +281,6 @@ struct rdp_peer_context { // RAIL support HANDLE vcm; - HANDLE eventVcm; RailServerContext* rail_server_context; DrdynvcServerContext* drdynvc_server_context; DispServerContext* disp_server_context; @@ -310,8 +309,10 @@ struct rdp_peer_context { struct wl_listener clientExec_destroy_listener; struct weston_surface *cursorSurface; // list of outstanding event_source sent from FreeRDP thread to display loop. + int loop_event_source_fd; pthread_mutex_t loop_event_source_list_mutex; struct wl_list loop_event_source_list; + // RAIL power management. struct wl_listener idle_listener; struct wl_listener wake_listener; @@ -447,6 +448,8 @@ void rdp_id_manager_free(struct rdp_id_manager *id_manager); BOOL rdp_id_manager_allocate_id(struct rdp_id_manager *id_manager, void *object, UINT32 *new_id); void rdp_id_manager_free_id(struct rdp_id_manager *id_manager, UINT32 id); void dump_id_manager_state(FILE *fp, struct rdp_id_manager *id_manager, char* title); +struct wl_event_source *rdp_defer_rdp_task_to_display_loop(RdpPeerContext *peerCtx, wl_event_loop_fd_func_t func, void *data); +void rdp_defer_rdp_task_done(RdpPeerContext *peerCtx); // rdprail.c int rdp_rail_backend_create(struct rdp_backend *b); @@ -477,29 +480,6 @@ void rdp_audioin_destroy(RdpPeerContext *peerCtx); int rdp_clipboard_init(freerdp_peer* client); void rdp_clipboard_destroy(RdpPeerContext *peerCtx); -/* this function is ONLY used to defer the task from RDP thread, - to be performed at wayland display loop thread */ -static inline struct wl_event_source * -rdp_defer_rdp_task_to_display_loop(RdpPeerContext *peerCtx, wl_event_loop_idle_func_t func, void *data) -{ - if (peerCtx->vcm) { - struct rdp_backend *b = peerCtx->rdpBackend; - ASSERT_NOT_COMPOSITOR_THREAD(b); - struct wl_event_loop *loop = wl_display_get_event_loop(b->compositor->wl_display); - struct wl_event_source *event_source = wl_event_loop_add_idle(loop, func, data); - if (event_source) { - SetEvent(peerCtx->eventVcm); - } else { - rdp_debug_error(b, "%s: wl_event_loop_add_idle failed\n", __func__); - } - return event_source; - } else { - /* RDP server is not opened, this must not be used */ - assert(false); - return NULL; - } -} - static inline struct rdp_head * to_rdp_head(struct weston_head *base) { diff --git a/libweston/backend-rdp/rdpclip.c b/libweston/backend-rdp/rdpclip.c index 6eb3beba2..f1304855a 100644 --- a/libweston/backend-rdp/rdpclip.c +++ b/libweston/backend-rdp/rdpclip.c @@ -101,7 +101,8 @@ enum rdp_clipboard_data_source_state { struct rdp_clipboard_data_source { struct weston_data_source base; - struct wl_event_source *event_source; + struct wl_event_source *transfer_event_source; /* used for read/write with pipe */ + struct wl_event_source *defer_event_source; /* used for defer task to display loop */ struct wl_array data_contents; void *context; int refcount; @@ -656,8 +657,13 @@ clipboard_data_source_unref(struct rdp_clipboard_data_source *source) if (source->refcount > 0) return; - if (source->event_source) - wl_event_source_remove(source->event_source); + if (source->transfer_event_source) + wl_event_source_remove(source->transfer_event_source); + + if (source->defer_event_source) { + rdp_defer_rdp_task_done(peerCtx); + wl_event_source_remove(source->defer_event_source); + } if (source->data_source_fd != -1) close(source->data_source_fd); @@ -698,6 +704,7 @@ clipboard_client_send_format_data_response(RdpPeerContext *peerCtx, struct rdp_c /* if here failed to send response, what can we do ? */ /* now client can send new data request */ + assert(peerCtx->clipboard_data_request_event_source == RDP_INVALID_EVENT_SOURCE); peerCtx->clipboard_data_request_event_source = NULL; return 0; @@ -726,6 +733,7 @@ clipboard_client_send_format_data_response_fail(RdpPeerContext *peerCtx, struct /* if here failed to send response, what can we do ? */ /* now client can send new data request */ + assert(peerCtx->clipboard_data_request_event_source == RDP_INVALID_EVENT_SOURCE); peerCtx->clipboard_data_request_event_source = NULL; return 0; @@ -757,7 +765,7 @@ clipboard_data_source_read(int fd, uint32_t mask, void *arg) /* event source is not removed here, but it will be removed when read is completed, until it's completed this function will be called whenever next chunk of data is available for read in pipe. */ - assert(source->event_source); + assert(source->transfer_event_source); /* if buffer is less than 1024 bytes remaining, request another 1024 bytes minimum */ /* but actual reallocated buffer size will be increased by ^2 */ @@ -836,13 +844,13 @@ clipboard_data_source_write(int fd, uint32_t mask, void *arg) assert(source == peerCtx->clipboard_inflight_client_data_source); /* remove event source now, and if write is failed with EAGAIN, queue back to display loop. */ - wl_event_source_remove(source->event_source); - source->event_source = NULL; + wl_event_source_remove(source->transfer_event_source); + source->transfer_event_source = NULL; if (source->is_canceled == FALSE && source->data_contents.data && source->data_contents.size) { if (source->inflight_data_to_write) { assert(source->inflight_data_size); - rdp_debug_clipboard_verbose(b, "RDP %s (%p:%s) retry write retry count:%d\n", + rdp_debug_clipboard_verbose(b, "RDP %s (%p:%s) transfer in chunck, count:%d\n", __func__, source, clipboard_data_source_state_to_string(source), source->inflight_write_count); data_to_write = source->inflight_data_to_write; data_size = source->inflight_data_size; @@ -864,13 +872,14 @@ clipboard_data_source_write(int fd, uint32_t mask, void *arg) __func__, source, clipboard_data_source_state_to_string(source), strerror(errno)); break; } + /* buffer is full, schedule write for next chunk. */ source->inflight_data_to_write = data_to_write; source->inflight_data_size = data_size; source->inflight_write_count++; - source->event_source = + source->transfer_event_source = wl_event_loop_add_fd(loop, source->data_source_fd, WL_EVENT_WRITABLE, clipboard_data_source_write, source); - if (!source->event_source) { + if (!source->transfer_event_source) { source->state = RDP_CLIPBOARD_SOURCE_FAILED; rdp_debug_clipboard_error(b, "RDP %s (%p:%s) wl_event_loop_add_fd failed\n", __func__, source, clipboard_data_source_state_to_string(source)); @@ -951,6 +960,7 @@ clipboard_data_source_send(struct weston_data_source *base, __func__, source, clipboard_data_source_state_to_string(source), peerCtx->clipboard_inflight_client_data_source, clipboard_data_source_state_to_string(peerCtx->clipboard_inflight_client_data_source)); + /* Here set error state after logging error, so log can show previous state. */ source->state = RDP_CLIPBOARD_SOURCE_FAILED; goto error_return_close_fd; } @@ -973,12 +983,12 @@ clipboard_data_source_send(struct weston_data_source *base, assert(source->inflight_data_size == 0); if (index == source->format_index) { /* data is already in data_contents, no need to pull from client */ - assert(source->event_source == NULL); + assert(source->transfer_event_source == NULL); source->state = RDP_CLIPBOARD_SOURCE_RECEIVED_DATA; - source->event_source = + source->transfer_event_source = wl_event_loop_add_fd(loop, source->data_source_fd, WL_EVENT_WRITABLE, clipboard_data_source_write, source); - if (!source->event_source) { + if (!source->transfer_event_source) { source->state = RDP_CLIPBOARD_SOURCE_FAILED; rdp_debug_clipboard_error(b, "RDP %s (%p:%s) wl_event_loop_add_fd failed\n", __func__, source, clipboard_data_source_state_to_string(source)); @@ -1053,7 +1063,7 @@ clipboard_data_source_cancel(struct weston_data_source *base) source->state = RDP_CLIPBOARD_SOURCE_CANCELED; rdp_debug_clipboard_verbose(b, "RDP %s (%p:%s)\n", __func__, source, clipboard_data_source_state_to_string(source)); - assert(source->event_source == NULL); + assert(source->transfer_event_source == NULL); wl_array_release(&source->data_contents); wl_array_init(&source->data_contents); source->is_data_processed = FALSE; @@ -1074,8 +1084,8 @@ clipboard_data_source_cancel(struct weston_data_source *base) \**********************************/ /* Publish client's available clipboard formats to compositor (make them visible to applications in server) */ -static void -clipboard_data_source_publish(void *arg) +static int +clipboard_data_source_publish(int fd, uint32_t mask, void *arg) { struct rdp_clipboard_data_source *source = (struct rdp_clipboard_data_source *)arg; freerdp_peer *client = (freerdp_peer*)source->context; @@ -1088,12 +1098,17 @@ clipboard_data_source_publish(void *arg) ASSERT_COMPOSITOR_THREAD(b); - /* here is going to publish new data, if previous data from us is still referenced, + rdp_defer_rdp_task_done(peerCtx); + assert(source->defer_event_source); + wl_event_source_remove(source->defer_event_source); + source->defer_event_source = NULL; + + /* here is going to publish new data, if previous data from client is still referenced, unref it after selection */ source_prev = peerCtx->clipboard_client_data_source; peerCtx->clipboard_client_data_source = source; - source->event_source = NULL; + source->transfer_event_source = NULL; source->base.accept = clipboard_data_source_accept; source->base.send = clipboard_data_source_send; source->base.cancel = clipboard_data_source_cancel; @@ -1104,12 +1119,12 @@ clipboard_data_source_publish(void *arg) if (source_prev) clipboard_data_source_unref(source_prev); - return; + return 0; } /* Request the specified clipboard data from data-device at server side */ -static void -clipboard_data_source_request(void *arg) +static int +clipboard_data_source_request(int fd, uint32_t mask, void *arg) { RdpPeerContext *peerCtx = (RdpPeerContext *)arg; struct rdp_backend *b = peerCtx->rdpBackend; @@ -1124,6 +1139,10 @@ clipboard_data_source_request(void *arg) ASSERT_COMPOSITOR_THREAD(b); + rdp_defer_rdp_task_done(peerCtx); + assert(peerCtx->clipboard_data_request_event_source); + assert(peerCtx->clipboard_data_request_event_source != RDP_INVALID_EVENT_SOURCE); + wl_event_source_remove(peerCtx->clipboard_data_request_event_source); /* set to invalid, so it still validate incoming request, but won't free event source at error. */ peerCtx->clipboard_data_request_event_source = RDP_INVALID_EVENT_SOURCE; @@ -1177,17 +1196,17 @@ clipboard_data_source_request(void *arg) /* p[1] should be closed by data source */ /* wait until data is ready on pipe */ - source->event_source = + source->transfer_event_source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE, clipboard_data_source_read, source); - if (!source->event_source) { + if (!source->transfer_event_source) { source->state = RDP_CLIPBOARD_SOURCE_FAILED; rdp_debug_clipboard_error(b, "RDP %s (%p:%s) wl_event_loop_add_fd failed.\n", __func__, source, clipboard_data_source_state_to_string(source)); goto error_exit_free_source; } - return; + return 0; error_exit_free_source: clipboard_data_source_unref(source); @@ -1195,7 +1214,7 @@ clipboard_data_source_request(void *arg) error_exit_response_fail: clipboard_client_send_format_data_response_fail(peerCtx, NULL); - return; + return 0; } /*************************************\ @@ -1228,7 +1247,7 @@ clipboard_set_selection(struct wl_listener *listener, void *data) } /* another data source (from server side) gets selected, - no longer need previous data from us */ + no longer need previous data from client. */ if (peerCtx->clipboard_client_data_source) { clipboard_data_source_unref(peerCtx->clipboard_client_data_source); peerCtx->clipboard_client_data_source = NULL; @@ -1387,11 +1406,11 @@ clipboard_client_format_list(CliprdrServerContext* context, const CLIPRDR_FORMAT } source->state = RDP_CLIPBOARD_SOURCE_FORMATLIST_READY; - source->event_source = + source->defer_event_source = rdp_defer_rdp_task_to_display_loop(peerCtx, clipboard_data_source_publish, source); - if (source->event_source) { + if (source->defer_event_source) { isPublished = TRUE; } else { source->state = RDP_CLIPBOARD_SOURCE_FAILED; @@ -1435,12 +1454,12 @@ clipboard_client_format_data_response(CliprdrServerContext* context, const CLIPR ASSERT_NOT_COMPOSITOR_THREAD(b); if (source) { - if (source->event_source || (source->inflight_write_count != 0)) { + if (source->transfer_event_source || (source->inflight_write_count != 0)) { /* here means client responded more than once for single data request */ source->state = RDP_CLIPBOARD_SOURCE_FAILED; rdp_debug_clipboard_error(b, "Client: %s (%p:%s) middle of write loop:%p, %d\n", __func__, source, clipboard_data_source_state_to_string(source), - source->event_source, source->inflight_write_count); + source->transfer_event_source, source->inflight_write_count); return -1; } @@ -1469,18 +1488,18 @@ clipboard_client_format_data_response(CliprdrServerContext* context, const CLIPR source->data_response_fail_count); if (Success) { - assert(source->event_source == NULL); - source->event_source = + assert(source->transfer_event_source == NULL); + source->transfer_event_source = wl_event_loop_add_fd(loop, source->data_source_fd, WL_EVENT_WRITABLE, clipboard_data_source_write, source); - if (!source->event_source) { + if (!source->transfer_event_source) { source->state = RDP_CLIPBOARD_SOURCE_FAILED; rdp_debug_clipboard_error(b, "Client: %s (%p:%s) wl_event_loop_add_fd failed\n", __func__, source, clipboard_data_source_state_to_string(source)); } } - if (!source->event_source) { + if (!source->transfer_event_source) { if (formatDataResponse->msgFlags == CB_RESPONSE_OK) { /* if data is recieved, but failed to sent to write(), then keep data and format index for future request, @@ -1662,6 +1681,7 @@ rdp_clipboard_destroy(RdpPeerContext *peerCtx) } if (peerCtx->clipboard_data_request_event_source && peerCtx->clipboard_data_request_event_source != RDP_INVALID_EVENT_SOURCE) { + rdp_defer_rdp_task_done(peerCtx); wl_event_source_remove(peerCtx->clipboard_data_request_event_source); peerCtx->clipboard_data_request_event_source = NULL; } diff --git a/libweston/backend-rdp/rdpdisp.c b/libweston/backend-rdp/rdpdisp.c index de78b26e2..3a3600826 100644 --- a/libweston/backend-rdp/rdpdisp.c +++ b/libweston/backend-rdp/rdpdisp.c @@ -603,19 +603,32 @@ disp_monitor_layout_change(DispServerContext* context, const DISPLAY_CONTROL_MON } struct disp_schedule_monitor_layout_change_data { - struct rdp_loop_event_source _base; + struct rdp_loop_event_source _base_event_source; DispServerContext* context; DISPLAY_CONTROL_MONITOR_LAYOUT_PDU displayControl; }; -static void -disp_monitor_layout_change_callback(void* dataIn) +static int +disp_monitor_layout_change_callback(int fd, uint32_t mask, void* dataIn) { struct disp_schedule_monitor_layout_change_data *data = (struct disp_schedule_monitor_layout_change_data *)dataIn; DispServerContext* context = data->context; - wl_list_remove(&data->_base.link); + freerdp_peer *client = (freerdp_peer*)context->custom; + RdpPeerContext *peerCtx = (RdpPeerContext *)client->context; + + ASSERT_COMPOSITOR_THREAD(peerCtx->rdpBackend); + + rdp_defer_rdp_task_done(peerCtx); + assert(data->_base_event_source.event_source); + wl_event_source_remove(data->_base_event_source.event_source); + pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); + wl_list_remove(&data->_base_event_source.link); + pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); + disp_monitor_layout_change(context, &data->displayControl); free(dataIn); + + return 0; } UINT @@ -643,16 +656,17 @@ disp_client_monitor_layout_change(DispServerContext* context, const DISPLAY_CONT memcpy(data->displayControl.Monitors, displayControl->Monitors, sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT) * displayControl->NumMonitors); - pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); \ - wl_list_insert(&peerCtx->loop_event_source_list, &data->_base.link); - pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); \ - data->_base.event_source = rdp_defer_rdp_task_to_display_loop(peerCtx, - disp_monitor_layout_change_callback, - data); - if (!data->_base.event_source) { - pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); \ - wl_list_remove(&data->_base.link); - pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); \ + pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); + wl_list_insert(&peerCtx->loop_event_source_list, &data->_base_event_source.link); + pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); + data->_base_event_source.event_source = + rdp_defer_rdp_task_to_display_loop(peerCtx, + disp_monitor_layout_change_callback, + data); + if (!data->_base_event_source.event_source) { + pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); + wl_list_remove(&data->_base_event_source.link); + pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); free(data); return ERROR_INTERNAL_ERROR; } diff --git a/libweston/backend-rdp/rdprail.c b/libweston/backend-rdp/rdprail.c index 634b305ac..255840d17 100644 --- a/libweston/backend-rdp/rdprail.c +++ b/libweston/backend-rdp/rdprail.c @@ -53,7 +53,7 @@ static void rdp_rail_schedule_update_window(struct wl_listener *listener, void * static void rdp_rail_dump_window_label(struct weston_surface *surface, char *label, uint32_t label_size); struct rdp_dispatch_data { - struct rdp_loop_event_source _base; + struct rdp_loop_event_source _base_event_source; freerdp_peer *client; union { RAIL_SYSPARAM_ORDER u_sysParam; @@ -82,14 +82,14 @@ struct rdp_dispatch_data { dispatch_data->client = client; \ dispatch_data->u_##arg_type = *(arg); \ pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); \ - wl_list_insert(&peerCtx->loop_event_source_list, &dispatch_data->_base.link); \ + wl_list_insert(&peerCtx->loop_event_source_list, &dispatch_data->_base_event_source.link); \ pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); \ - dispatch_data->_base.event_source = \ + dispatch_data->_base_event_source.event_source = \ rdp_defer_rdp_task_to_display_loop(peerCtx, callback, dispatch_data); \ - if (!dispatch_data->_base.event_source) { \ + if (!dispatch_data->_base_event_source.event_source) { \ rdp_debug_error(b, "%s: rdp_queue_deferred_task failed\n", __func__); \ pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); \ - wl_list_remove(&dispatch_data->_base.link); \ + wl_list_remove(&dispatch_data->_base_event_source.link); \ pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); \ free(dispatch_data); \ } \ @@ -101,15 +101,19 @@ struct rdp_dispatch_data { #define RDP_DISPATCH_DISPLAY_LOOP_COMPLETED(peerCtx, dispatch_data) \ { \ ASSERT_COMPOSITOR_THREAD(peerCtx->rdpBackend); \ + rdp_defer_rdp_task_done(peerCtx); \ + assert(dispatch_data->_base_event_source.event_source); \ + wl_event_source_remove(dispatch_data->_base_event_source.event_source); \ pthread_mutex_lock(&peerCtx->loop_event_source_list_mutex); \ - wl_list_remove(&dispatch_data->_base.link); \ + wl_list_remove(&dispatch_data->_base_event_source.link); \ pthread_mutex_unlock(&peerCtx->loop_event_source_list_mutex); \ free(dispatch_data); \ + return 0; \ } #ifdef HAVE_FREERDP_RDPAPPLIST_H -static void -applist_client_Caps_callback(void *arg) +static int +applist_client_Caps_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RDPAPPLIST_CLIENT_CAPS_PDU* caps = &data->u_appListCaps; @@ -172,8 +176,8 @@ rail_ClientExec_destroy(struct wl_listener *listener, void *data) peerCtx->clientExec = NULL; } -static void -rail_client_Exec_callback(void *arg) +static int +rail_client_Exec_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_EXEC_ORDER* exec = &data->u_exec; @@ -286,8 +290,8 @@ rail_client_Exec(RailServerContext* context, const RAIL_EXEC_ORDER* arg) return CHANNEL_RC_NO_BUFFER; } -static void -rail_client_Activate_callback(void *arg) +static int +rail_client_Activate_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_ACTIVATE_ORDER* activate = &data->u_activate; @@ -321,8 +325,8 @@ rail_client_Activate(RailServerContext* context, const RAIL_ACTIVATE_ORDER* arg) return CHANNEL_RC_OK; } -static void -rail_client_SnapArrange_callback(void *arg) +static int +rail_client_SnapArrange_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_SNAP_ARRANGE* snap = &data->u_snapArrange; @@ -368,8 +372,8 @@ rail_client_SnapArrange(RailServerContext* context, const RAIL_SNAP_ARRANGE* arg return CHANNEL_RC_OK; } -static void -rail_client_WindowMove_callback(void *arg) +static int +rail_client_WindowMove_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_WINDOW_MOVE_ORDER* windowMove = &data->u_windowMove; @@ -410,8 +414,8 @@ rail_client_WindowMove(RailServerContext* context, const RAIL_WINDOW_MOVE_ORDER* return CHANNEL_RC_OK; } -static void -rail_client_Syscommand_callback(void *arg) +static int +rail_client_Syscommand_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_SYSCOMMAND_ORDER* syscommand = &data->u_sysCommand; @@ -485,8 +489,8 @@ rail_client_Syscommand(RailServerContext* context, const RAIL_SYSCOMMAND_ORDER* return CHANNEL_RC_OK; } -static void -rail_client_ClientSysparam_callback(void *arg) +static int +rail_client_ClientSysparam_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_SYSPARAM_ORDER* sysparam = &data->u_sysParam; @@ -609,8 +613,8 @@ rail_client_ClientSysparam(RailServerContext* context, const RAIL_SYSPARAM_ORDER return CHANNEL_RC_OK; } -static void -rail_client_ClientGetAppidReq_callback(void *arg) +static int +rail_client_ClientGetAppidReq_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_GET_APPID_REQ_ORDER* getAppidReq = &data->u_getAppidReq; @@ -787,8 +791,8 @@ languageGuid_to_string(const GUID *guid) return "Unknown GUID"; } -static void -rail_client_LanguageImeInfo_callback(void *arg) +static int +rail_client_LanguageImeInfo_callback(int fd, uint32_t mask, void *arg) { struct rdp_dispatch_data* data = (struct rdp_dispatch_data*)arg; const RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo = &data->u_languageImeInfo; diff --git a/libweston/backend-rdp/rdputil.c b/libweston/backend-rdp/rdputil.c index 931366884..e0163cb82 100644 --- a/libweston/backend-rdp/rdputil.c +++ b/libweston/backend-rdp/rdputil.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -294,4 +295,37 @@ dump_id_manager_state(FILE *fp, struct rdp_id_manager *id_manager, char* title) fprintf(fp,"\n"); } +/* this function is ONLY used to defer the task from RDP thread, + to be performed at wayland display loop thread */ +struct wl_event_source * +rdp_defer_rdp_task_to_display_loop(RdpPeerContext *peerCtx, wl_event_loop_fd_func_t func, void *data) +{ + if (peerCtx->vcm) { + struct rdp_backend *b = peerCtx->rdpBackend; + ASSERT_NOT_COMPOSITOR_THREAD(b); + struct wl_event_loop *loop = wl_display_get_event_loop(b->compositor->wl_display); + struct wl_event_source *event_source = + wl_event_loop_add_fd(loop, + peerCtx->loop_event_source_fd, + WL_EVENT_READABLE, + func, data); + if (event_source) { + eventfd_write(peerCtx->loop_event_source_fd, 1); + } else { + rdp_debug_error(b, "%s: wl_event_loop_add_idle failed\n", __func__); + } + return event_source; + } else { + /* RDP server is not opened, this must not be used */ + assert(false); + return NULL; + } +} + +void +rdp_defer_rdp_task_done(RdpPeerContext *peerCtx) +{ + eventfd_t dummy; + eventfd_read(peerCtx->loop_event_source_fd, &dummy); +}