wfreerdp-server: add support for parallel sending to multiple clients
This commit is contained in:
parent
c59b7dedad
commit
271aa3edb5
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user