wfreerdp-server: start cleaning up mutex access

This commit is contained in:
Marc-André Moreau 2012-09-02 18:04:41 -04:00
parent 2234e3bb70
commit 7a0a8c3eb2
6 changed files with 93 additions and 114 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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"),

View File

@ -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);

View File

@ -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;
}
}

View File

@ -21,6 +21,7 @@
#define WFREERDP_H
//#define WITH_WIN8 1
//#define WITH_DOUBLE_BUFFERING 1
#include <freerdp/freerdp.h>
#include <freerdp/codec/rfx.h>