From 7a0a8c3eb285cb695f50524e6aea7dbd4509cb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 2 Sep 2012 18:04:41 -0400 Subject: [PATCH] wfreerdp-server: start cleaning up mutex access --- server/Windows/wf_info.c | 94 +++++++++++++++++++++----------------- server/Windows/wf_info.h | 15 +++--- server/Windows/wf_mirage.c | 4 +- server/Windows/wf_mirage.h | 2 +- server/Windows/wf_peer.c | 91 +++++++++++++----------------------- server/Windows/wfreerdp.h | 1 + 6 files changed, 93 insertions(+), 114 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 903d1a779..95bd78a02 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -29,53 +29,80 @@ #include "wf_info.h" #include "wf_mirage.h" -extern wfInfo * wfInfoSingleton; - static wfInfo* wfInfoInstance = NULL; -int wf_info_lock(wfInfo* wfi, DWORD ms) +int wf_info_lock(wfInfo* wfi) { DWORD dRes; - dRes = WaitForSingleObject(wfi->mutex, ms); + dRes = WaitForSingleObject(wfi->mutex, INFINITE); switch (dRes) { case WAIT_ABANDONED: - printf("Got ownership of abandoned mutex... resuming...\n"); - break; - case WAIT_OBJECT_0: + return TRUE; break; case WAIT_TIMEOUT: - return 1; + return FALSE; break; case WAIT_FAILED: - printf("WAIT FAILED code %#X\n", GetLastError()); + printf("wf_info_lock failed with 0x%08X\n", GetLastError()); return -1; break; } - return 0; + return -1; +} + +int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) +{ + DWORD dRes; + + dRes = WaitForSingleObject(wfi->mutex, dwMilliseconds); + + switch (dRes) + { + case WAIT_ABANDONED: + case WAIT_OBJECT_0: + return TRUE; + break; + + case WAIT_TIMEOUT: + return FALSE; + break; + + case WAIT_FAILED: + printf("wf_info_try_lock failed with 0x%08X\n", GetLastError()); + return -1; + break; + } + + return -1; } int wf_info_unlock(wfInfo* wfi) { if (ReleaseMutex(wfi->mutex) == 0) - return 0; + { + printf("wf_info_unlock failed with 0x%08X\n", GetLastError()); + return -1; + } - return 1; + return TRUE; } -wfInfo* wf_info_init(wfInfo* wfi) +wfInfo* wf_info_init() { - if (!wfi) - { - wfi = (wfInfo*) malloc(sizeof(wfInfo)); - ZeroMemory(wfi, sizeof(wfInfo)); + wfInfo* wfi; + wfi = (wfInfo*) malloc(sizeof(wfInfo)); + ZeroMemory(wfi, sizeof(wfInfo)); + + if (wfi != NULL) + { wfi->mutex = CreateMutex(NULL, FALSE, NULL); if (wfi->mutex == NULL) @@ -104,7 +131,7 @@ wfInfo* wf_info_init(wfInfo* wfi) wfInfo* wf_info_get_instance() { if (wfInfoInstance == NULL) - wfInfoInstance = wf_info_init(NULL); + wfInfoInstance = wf_info_init(); return wfInfoInstance; } @@ -117,15 +144,16 @@ void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context) switch (dRes) { + case WAIT_ABANDONED: case WAIT_OBJECT_0: - if (wfi->subscribers == 0) + if (wfi->subscribers < 1) { /* only the first peer needs to call this. */ context->info = wfi; wf_check_disp_devices(context->info); - wf_disp_device_set_attatch(context->info, 1); + wf_disp_device_set_attach_mode(context->info, 1); wf_update_mirror_drv(context->info, 0); wf_map_mirror_mem(context->info); @@ -137,9 +165,8 @@ void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context) rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); context->s = stream_new(65536); - context->info->roflbuffer = (BYTE*)malloc( (context->info->width) * (context->info->height) * 4); + context->info->primary_buffer = (BYTE*) malloc((context->info->width) * (context->info->height) * 4); - printf("Start Encoder\n"); ReleaseMutex(wfi->encodeMutex); } ++wfi->subscribers; @@ -181,13 +208,13 @@ void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context) --wfi->subscribers; /* only the last peer needs to call this */ wf_mirror_cleanup(context->info); - wf_disp_device_set_attatch(context->info, 0); + wf_disp_device_set_attach_mode(context->info, FALSE); wf_update_mirror_drv(context->info, 1); stream_free(context->s); rfx_context_free(context->rfx_context); - free(context->info->roflbuffer); + free(context->info->primary_buffer); break; /** @@ -220,7 +247,6 @@ BOOL wf_info_has_subscribers(wfInfo* wfi) return FALSE; } - BOOL wf_info_have_updates(wfInfo* wfi) { if (wfi->nextUpdate == wfi->lastUpdate) @@ -299,21 +325,3 @@ BOOL wf_info_have_invalid_region(wfInfo* wfi) return TRUE; } - -int wf_info_get_thread_count(wfInfo* wfi) -{ - int count; - - WaitForSingleObject(wfi->mutex, INFINITE); - count = wfi->threadCnt; - ReleaseMutex(wfi->mutex); - - return count; -} - -void wf_info_set_thread_count(wfInfo* wfi, int count) -{ - WaitForSingleObject(wfi->mutex, INFINITE); - wfi->threadCnt = count; - ReleaseMutex(wfi->mutex); -} diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index cbe85970f..b67051ce1 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -31,12 +31,14 @@ struct wf_info LPTSTR deviceKey; TCHAR deviceName[32]; int subscribers; - int threadCnt; + int threadCount; int height; int width; int bitsPerPix; - HANDLE mutex, encodeMutex, can_send_mutex; + HANDLE mutex; + HANDLE encodeMutex; + HANDLE can_send_mutex; unsigned long lastUpdate; unsigned long nextUpdate; @@ -49,21 +51,18 @@ struct wf_info BOOL enc_data; - BYTE* roflbuffer; + BYTE* primary_buffer; }; typedef struct wf_info wfInfo; -int wf_info_lock(wfInfo* wfi, DWORD ms); +int wf_info_lock(wfInfo* wfi); +int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); int wf_info_unlock(wfInfo* wfi); wfInfo* wf_info_get_instance(); -wfInfo* wf_info_init(wfInfo* wfi); void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context); void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context); -int wf_info_get_thread_count(wfInfo* wfi); -void wf_info_set_thread_count(wfInfo* wfi, int count); - BOOL wf_info_has_subscribers(wfInfo* wfi); BOOL wf_info_have_updates(wfInfo* wfi); void wf_info_updated(wfInfo* wfi); diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index 057508c03..f5d09f684 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -78,7 +78,7 @@ BOOL wf_check_disp_devices(wfInfo* context) * false. */ -BOOL wf_disp_device_set_attatch(wfInfo* context, DWORD val) +BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode) { HKEY hKey; LONG status; @@ -101,7 +101,7 @@ BOOL wf_disp_device_set_attatch(wfInfo* context, DWORD val) if (dwValue == 1) { - dwValue = val; + dwValue = mode; dwSize = sizeof(DWORD); status = RegSetValueEx(HKEY_LOCAL_MACHINE, _T("Attach.ToDesktop"), diff --git a/server/Windows/wf_mirage.h b/server/Windows/wf_mirage.h index 60813a653..7ea5f2f1e 100644 --- a/server/Windows/wf_mirage.h +++ b/server/Windows/wf_mirage.h @@ -201,7 +201,7 @@ typedef struct } Esc_dmf_pointer_shape_get_OUT; BOOL wf_check_disp_devices(wfInfo* context); -BOOL wf_disp_device_set_attatch(wfInfo* context, DWORD val); +BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode); BOOL wf_update_mirror_drv(wfInfo* context, int unload); BOOL wf_map_mirror_mem(wfInfo* context); BOOL wf_mirror_cleanup(wfInfo* context); diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 9f27c79b0..3745e241c 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -67,7 +67,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) { beg = GetTickCount(); - wf_info_lock(wfi, INFINITE); + wf_info_lock(wfi); if (wf_info_has_subscribers(wfi)) { @@ -76,10 +76,6 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) if (wf_info_have_updates(wfi)) wf_rfx_encode(client); } - else - { - wf_info_unlock(wfi); - } wf_info_unlock(wfi); @@ -92,9 +88,9 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) } } - - _tprintf(_T("monitor thread terminating...\n")); - wf_info_set_thread_count(wfi, wf_info_get_thread_count(wfi) - 1); + wf_info_lock(wfi); + wfi->threadCount--; + wf_info_unlock(wfi); return 0; } @@ -112,9 +108,8 @@ void wf_rfx_encode(freerdp_peer* client) GETCHANGESBUF* buf; SURFACE_BITS_COMMAND* cmd; -#ifdef ROFLBUFFER +#ifdef WITH_DOUBLE_BUFFERING uint16 i; - int delta; int scanline; BYTE* srcp; BYTE* dstp; @@ -131,13 +126,11 @@ void wf_rfx_encode(freerdp_peer* client) switch (dRes) { case WAIT_ABANDONED: - printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... resuming...\n"); - case WAIT_OBJECT_0: wf_info_find_invalid_region(wfi); - if( (wfp->activated == false) || + if ((wfp->activated == false) || (wf_info_has_subscribers(wfi) == false) || !wf_info_have_invalid_region(wfi) || (wfi->enc_data == true) ) @@ -161,36 +154,19 @@ void wf_rfx_encode(freerdp_peer* client) rect.y = 0; rect.width = (uint16) width; rect.height = (uint16) height; - - //printf("Encoding: left:%d top:%d right:%d bottom:%d width:%d height:%d\n", - // wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2, width, height); - -#ifndef ROFLBUFFER +#ifndef WITH_DOUBLE_BUFFERING offset = (4 * wfi->invalid_x1) + (wfi->invalid_y1 * wfi->width * 4); rfx_compose_message(wfp->rfx_context, s, &rect, 1, ((uint8*) (buf->Userbuffer)) + offset, width, height, wfi->width * 4); #else - - //memcpy(wfi->roflbuffer, ((uint8*) (buf->Userbuffer)) + offset, 4 * width * height); - - //to copy the region we must copy HxWxB bytes per line and skip 4*(screen_w - x2) - - - /*delta = 0; - for(i = 0; i < height; ++i) - { - memcpy(wfi->roflbuffer + offset + delta, ((uint8*) (buf->Userbuffer)) + offset + delta, 4 * width); - delta += (4 * width) + (4 * (wfi->width - wfi->invalid_x2) + (4 * wfi->invalid_x1)); - }*/ - scanline = (wfi->width * 4); offset = (wfi->invalid_y1 * scanline) + (wfi->invalid_x1 * 4); srcp = (BYTE*) buf->Userbuffer + offset; - dstp = (BYTE*) wfi->roflbuffer + offset; - Sleep(100); + dstp = (BYTE*) wfi->primary_buffer + offset; + for (i = 0; i < height; i++) { memcpy(dstp, srcp, width * 4); @@ -199,8 +175,7 @@ void wf_rfx_encode(freerdp_peer* client) } rfx_compose_message(wfp->rfx_context, s, &rect, 1, - wfi->roflbuffer + offset, width, height, wfi->width * 4); - + wfi->primary_buffer + offset, width, height, wfi->width * 4); #endif cmd->destLeft = wfi->invalid_x1; @@ -225,7 +200,6 @@ void wf_rfx_encode(freerdp_peer* client) break; default: - printf("\n\nwf_rfx_encode: Something else happened!!! dRes = %d\n", dRes); break; } @@ -244,17 +218,22 @@ void wf_peer_init(freerdp_peer* client) wfi = ((wfPeerContext*) client->context)->info; #ifndef WITH_WIN8 - if (!wf_info_get_thread_count(wfi)) + wf_info_lock(wfi); + + if (wfi->threadCount < 1) { if (CreateThread(NULL, 0, wf_peer_mirror_monitor, client, 0, NULL) != 0) { - wf_info_set_thread_count(wfi, wf_info_get_thread_count(wfi) + 1); + wfi->threadCount++; + printf("started monitor thread\n"); } else { _tprintf(_T("failed to create monitor thread\n")); } } + + wf_info_unlock(wfi); #endif } @@ -323,42 +302,34 @@ void wf_peer_send_changes(freerdp_peer* client) /* are we currently encoding? */ dRes = WaitForSingleObject(wfi->encodeMutex, 0); - switch(dRes) + switch (dRes) { case WAIT_ABANDONED: - - printf("\n\nwf_peer_send_changes: Got ownership of abandoned mutex... resuming...\n"); - /* no break; */ - case WAIT_OBJECT_0: - /* are there changes to send? */ - - if ( ((wf_info_lock(wfi, 0) != 0)) || - !wf_info_have_updates(wfi) || - !wf_info_have_invalid_region(wfi) || - (wfi->enc_data == FALSE)) + if (wf_info_try_lock(wfi, 100) != -1) { - /* we do not send */ + if ((!wf_info_have_updates(wfi) || !wf_info_have_invalid_region(wfi) || (wfi->enc_data == FALSE))) + { + wf_info_unlock(wfi); + ReleaseMutex(wfi->encodeMutex); + break; + } + + wf_info_updated(wfi); + + client->update->SurfaceBits(client->update->context, &client->update->surface_bits_command); + + wfi->enc_data = FALSE; wf_info_unlock(wfi); ReleaseMutex(wfi->encodeMutex); - break; } - - wf_info_updated(wfi); - - client->update->SurfaceBits(client->update->context, &client->update->surface_bits_command); - - wfi->enc_data = FALSE; - wf_info_unlock(wfi); - ReleaseMutex(wfi->encodeMutex); break; case WAIT_TIMEOUT: break; default: - printf("wf_peer_send_changes: Something else happened!!! dRes = %d\n", dRes); break; } } diff --git a/server/Windows/wfreerdp.h b/server/Windows/wfreerdp.h index 021d0e371..dce836d8b 100644 --- a/server/Windows/wfreerdp.h +++ b/server/Windows/wfreerdp.h @@ -21,6 +21,7 @@ #define WFREERDP_H //#define WITH_WIN8 1 +//#define WITH_DOUBLE_BUFFERING 1 #include #include