wfreerdp-server: start cleaning up mutex access
This commit is contained in:
parent
2234e3bb70
commit
7a0a8c3eb2
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user