Skip to content

Commit

Permalink
shadow fix multi-client hang
Browse files Browse the repository at this point in the history
Merge from commit d4df3a9
Conflicts:

	server/shadow/shadow_subsystem.c
realjiangms committed May 10, 2015
1 parent d4df3a9 commit 85dd90d
Showing 10 changed files with 437 additions and 40 deletions.
4 changes: 2 additions & 2 deletions include/freerdp/server/shadow.h
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ typedef struct rdp_shadow_surface rdpShadowSurface;
typedef struct rdp_shadow_encoder rdpShadowEncoder;
typedef struct rdp_shadow_capture rdpShadowCapture;
typedef struct rdp_shadow_subsystem rdpShadowSubsystem;
typedef struct rdp_shadow_multiclient_event rdpShadowMultiClientEvent;

typedef struct _RDP_SHADOW_ENTRY_POINTS RDP_SHADOW_ENTRY_POINTS;
typedef int (*pfnShadowSubsystemEntry)(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
@@ -143,11 +144,10 @@ struct _RDP_SHADOW_ENTRY_POINTS
int selectedMonitor; \
MONITOR_DEF monitors[16]; \
MONITOR_DEF virtualScreen; \
HANDLE updateEvent; \
rdpShadowMultiClientEvent* updateEvent; \
BOOL suppressOutput; \
REGION16 invalidRegion; \
wMessagePipe* MsgPipe; \
SYNCHRONIZATION_BARRIER barrier; \
UINT32 pointerX; \
UINT32 pointerY; \
\
2 changes: 2 additions & 0 deletions server/shadow/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -171,6 +171,8 @@ set(${MODULE_PREFIX}_SRCS
shadow_remdesk.h
shadow_subsystem.c
shadow_subsystem.h
shadow_mcevent.c
shadow_mcevent.h
shadow_server.c
shadow.h)

11 changes: 2 additions & 9 deletions server/shadow/Mac/mac_shadow.c
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
#include "../shadow_capture.h"
#include "../shadow_encoder.h"
#include "../shadow_subsystem.h"
#include "../shadow_mcevent.h"

#include "mac_shadow.h"

@@ -366,13 +367,7 @@ void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfa

count = ArrayList_Count(server->clients);

InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

SetEvent(subsystem->updateEvent);

EnterSynchronizationBarrier(&(subsystem->barrier), 0);

DeleteSynchronizationBarrier(&(subsystem->barrier));
shadow_multiclient_publish_and_wait(subsystem->updateEvent);

if (count == 1)
{
@@ -386,8 +381,6 @@ void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfa
}
}

ResetEvent(subsystem->updateEvent);

ArrayList_Unlock(server->clients);

region16_clear(&(subsystem->invalidRegion));
10 changes: 2 additions & 8 deletions server/shadow/Win/win_shadow.c
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
#include "../shadow_surface.h"
#include "../shadow_capture.h"
#include "../shadow_subsystem.h"
#include "../shadow_mcevent.h"

#include "win_shadow.h"

@@ -287,14 +288,7 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)

count = ArrayList_Count(server->clients);

InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

SetEvent(subsystem->updateEvent);

EnterSynchronizationBarrier(&(subsystem->barrier), 0);
ResetEvent(subsystem->updateEvent);

DeleteSynchronizationBarrier(&(subsystem->barrier));
shadow_multiclient_publish_and_wait(subsystem->updateEvent);

ArrayList_Unlock(server->clients);

11 changes: 2 additions & 9 deletions server/shadow/X11/x11_shadow.c
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@
#include "../shadow_capture.h"
#include "../shadow_surface.h"
#include "../shadow_subsystem.h"
#include "../shadow_mcevent.h"

#include "x11_shadow.h"

@@ -708,13 +709,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)

count = ArrayList_Count(server->clients);

InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

SetEvent(subsystem->updateEvent);

EnterSynchronizationBarrier(&(subsystem->barrier), 0);

DeleteSynchronizationBarrier(&(subsystem->barrier));
shadow_multiclient_publish_and_wait(subsystem->updateEvent);

if (count == 1)
{
@@ -728,8 +723,6 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
}
}

ResetEvent(subsystem->updateEvent);

region16_clear(&(subsystem->invalidRegion));
}

1 change: 1 addition & 0 deletions server/shadow/shadow.h
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
#include "shadow_channels.h"
#include "shadow_subsystem.h"
#include "shadow_lobby.h"
#include "shadow_mcevent.h"

#ifdef __cplusplus
extern "C" {
30 changes: 21 additions & 9 deletions server/shadow/shadow_client.c
Original file line number Diff line number Diff line change
@@ -952,6 +952,7 @@ void* shadow_client_thread(rdpShadowClient* client)
HANDLE StopEvent;
HANDLE ClientEvent;
HANDLE ChannelEvent;
void* UpdateSubscriber;
HANDLE UpdateEvent;
freerdp_peer* peer;
rdpContext* context;
@@ -983,8 +984,15 @@ void* shadow_client_thread(rdpShadowClient* client)
peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output;
peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge) shadow_client_surface_frame_acknowledge;

if ((!client->StopEvent) || (!client->vcm) || (!subsystem->updateEvent))
goto out;

UpdateSubscriber = shadow_multiclient_get_subscriber(subsystem->updateEvent);
if (!UpdateSubscriber)
goto out;

StopEvent = client->StopEvent;
UpdateEvent = subsystem->updateEvent;
UpdateEvent = shadow_multiclient_getevent(UpdateSubscriber);
ClientEvent = peer->GetEventHandle(peer);
ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);

@@ -1001,11 +1009,6 @@ void* shadow_client_thread(rdpShadowClient* client)

if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
{
if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
{
EnterSynchronizationBarrier(&(subsystem->barrier), 0);
}

break;
}

@@ -1027,9 +1030,11 @@ void* shadow_client_thread(rdpShadowClient* client)
shadow_client_send_surface_update(client);
}

EnterSynchronizationBarrier(&(subsystem->barrier), 0);

while (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0);
/*
* The return value of shadow_multiclient_consume is whether or not the subscriber really consumes the event.
* It's not cared currently.
*/
(void)shadow_multiclient_consume(UpdateSubscriber);
}

if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
@@ -1062,6 +1067,13 @@ void* shadow_client_thread(rdpShadowClient* client)
}
}

if (UpdateSubscriber)
{
shadow_multiclient_release_subscriber(UpdateSubscriber);
UpdateSubscriber = NULL;
}

out:
peer->Disconnect(peer);

freerdp_peer_context_free(peer);
Loading
Oops, something went wrong.

0 comments on commit 85dd90d

Please sign in to comment.