diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 94a5aa25d..366566951 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -117,7 +117,9 @@ wfInfo* wf_info_init() _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - wfi->updateEvent = CreateEvent(0, 1, 0, 0); + wfi->updateEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + wfi->updateSemaphore = CreateSemaphore(NULL, 0, 32, NULL); wfi->updateThread = CreateThread(NULL, 0, wf_update_thread, wfi, CREATE_SUSPENDED, NULL); @@ -179,21 +181,30 @@ void wf_update_encoder_reinit(wfInfo* wfi) wf_update_encoder_init(wfi); } +void wf_mirror_driver_init(wfInfo* wfi) +{ + wf_mirror_driver_find_display_device(wfi); + wf_mirror_driver_display_device_attach(wfi, 1); + wf_mirror_driver_update(wfi, FALSE); + wf_mirror_driver_map_memory(wfi); +} + +void wf_mirror_driver_uninit(wfInfo* wfi) +{ + wf_mirror_driver_cleanup(wfi); + wf_mirror_driver_display_device_attach(wfi, 0); + wf_mirror_driver_update(wfi, 1); +} + void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) { if (wf_info_lock(wfi) > 0) { context->info = wfi; + context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (wfi->peerCount < 1) - { - wf_mirror_driver_find_display_device(wfi); - wf_mirror_driver_display_device_attach(wfi, 1); - wf_mirror_driver_update(wfi, FALSE); - wf_mirror_driver_map_memory(wfi); - - //wf_update_encoder_init(wfi); - } + wf_mirror_driver_init(wfi); wf_update_encoder_reinit(wfi); wfi->peers[wfi->peerCount++] = context; @@ -206,20 +217,10 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) { if (wf_info_lock(wfi) > 0) { - if (wfi->peerCount <= 1) - { - wfi->peers[--(wfi->peerCount)] = NULL; + if (wfi->peerCount == 1) + wf_mirror_driver_uninit(wfi); - wf_mirror_driver_cleanup(wfi); - wf_mirror_driver_display_device_attach(wfi, 0); - wf_mirror_driver_update(wfi, 1); - - //wf_update_encoder_uninit(wfi); - } - else - { - wfi->peers[--(wfi->peerCount)] = NULL; - } + wfi->peers[--(wfi->peerCount)] = NULL; wf_info_unlock(wfi); } diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 6eb995798..be81bf3e1 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -46,6 +46,7 @@ struct wf_info BOOL updatePending; HANDLE updateEvent; HANDLE updateThread; + HANDLE updateSemaphore; RFX_CONTEXT* rfx_context; unsigned long lastUpdate; unsigned long nextUpdate; diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index c4ca0f2cb..57b3c94e8 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -33,6 +33,7 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) { + int index; DWORD fps; wfInfo* wfi; DWORD beg, end; @@ -56,7 +57,14 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) if (wf_info_have_updates(wfi)) { wf_update_encode(wfi); - SetEvent(wfi->updateEvent); + + for (index = 0; index < wfi->peerCount; index++) + SetEvent(wfi->peers[index]->updateEvent); + + for (index = 0; index < wfi->peerCount; index++) + WaitForSingleObject(wfi->updateSemaphore, INFINITE); + + wfi->lastUpdate = wfi->nextUpdate; } } @@ -115,30 +123,11 @@ void wf_update_encode(wfInfo* wfi) cmd->height = height; cmd->bitmapDataLength = stream_get_length(wfi->s); cmd->bitmapData = stream_get_head(wfi->s); - - wfi->updatePending = TRUE; } -void wf_update_send(wfInfo* wfi) +void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context) { - if (wf_info_lock(wfi) > 0) - { - if (wfi->updatePending) - { - int index; - freerdp_peer* client; - - for (index = 0; index < wfi->peerCount; index++) - { - client = ((rdpContext*) wfi->peers[index])->peer; - wfi->cmd.codecID = client->settings->rfx_codec_id; - client->update->SurfaceBits(client->update->context, &wfi->cmd); - } - - wfi->lastUpdate = wfi->nextUpdate; - wfi->updatePending = FALSE; - } - - wf_info_unlock(wfi); - } + freerdp_peer* client = ((rdpContext*) context)->peer; + wfi->cmd.codecID = client->settings->rfx_codec_id; + client->update->SurfaceBits(client->update->context, &wfi->cmd); } diff --git a/server/Windows/wf_update.h b/server/Windows/wf_update.h index b214f2d34..98f6ca25d 100644 --- a/server/Windows/wf_update.h +++ b/server/Windows/wf_update.h @@ -27,4 +27,8 @@ void wf_update_send(wfInfo* wfi); DWORD WINAPI wf_update_thread(LPVOID lpParam); +void wf_update_begin(wfInfo* wfi); +void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context); +void wf_update_end(wfInfo* wfi); + #endif /* WF_UPDATE_H */ diff --git a/server/Windows/wfreerdp.c b/server/Windows/wfreerdp.c index 1597857e6..f2fb0e74f 100644 --- a/server/Windows/wfreerdp.c +++ b/server/Windows/wfreerdp.c @@ -58,13 +58,16 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) memset(rfds, 0, sizeof(rfds)); context = (wfPeerContext*) client->context; + context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL); + while (1) { rcount = 0; if (client->GetFileDescriptor(client, rfds, &rcount) != true) { - printf("Failed to get FreeRDP file descriptor\n"); + printf("Failed to get peer file descriptor\n"); break; } @@ -87,6 +90,10 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) select(max_fds + 1, &rfds_set, NULL, NULL, NULL); SetEvent(context->socketEvent); + WaitForSingleObject(context->socketSemaphore, INFINITE); + + if (context->socketClose) + break; } return 0; @@ -168,15 +175,15 @@ static void wf_peer_read_settings(freerdp_peer* client) static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) { + wfInfo* wfi; DWORD nCount; + DWORD status; HANDLE handles[32]; wfPeerContext* context; freerdp_peer* client = (freerdp_peer*) lpParam; wf_peer_init(client); - /* Initialize the real server settings here */ - wf_peer_read_settings(client); client->PostConnect = wf_peer_post_connect; @@ -191,29 +198,42 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) client->Initialize(client); context = (wfPeerContext*) client->context; - context->socketEvent = CreateEvent(0, 1, 0, 0); - CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL); + wfi = context->info; + context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL); printf("We've got a client %s\n", client->local ? "(local)" : client->hostname); nCount = 0; + handles[nCount++] = context->updateEvent; handles[nCount++] = context->socketEvent; - handles[nCount++] = context->info->updateEvent; while (1) { - DWORD status; - status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); - if (client->CheckFileDescriptor(client) != true) + if (WaitForSingleObject(context->updateEvent, 0) == 0) { - printf("Failed to check FreeRDP file descriptor\n"); - break; + if (client->activated) + wf_update_peer_send(wfi, context); + + ResetEvent(context->updateEvent); + ReleaseSemaphore(wfi->updateSemaphore, 1, NULL); } - if (client->activated) - wf_update_send(context->info); + if (WaitForSingleObject(context->socketEvent, 0) == 0) + { + if (client->CheckFileDescriptor(client) != true) + { + printf("Failed to check peer file descriptor\n"); + context->socketClose = TRUE; + } + + ResetEvent(context->socketEvent); + ReleaseSemaphore(context->socketSemaphore, 1, NULL); + + if (context->socketClose) + break; + } } printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); diff --git a/server/Windows/wfreerdp.h b/server/Windows/wfreerdp.h index 38b18558e..7f804fa07 100644 --- a/server/Windows/wfreerdp.h +++ b/server/Windows/wfreerdp.h @@ -30,7 +30,11 @@ struct wf_peer_context wfInfo* info; boolean activated; + HANDLE updateEvent; + BOOL socketClose; HANDLE socketEvent; + HANDLE socketThread; + HANDLE socketSemaphore; }; typedef struct wf_peer_context wfPeerContext;