xfreerdp-server: add event queue

This commit is contained in:
Marc-André Moreau 2012-01-30 22:46:02 -05:00
parent 5356e5a44e
commit 589e9e1142
5 changed files with 127 additions and 58 deletions

View File

@ -38,7 +38,10 @@ void* xmalloc(size_t size)
mem = malloc(size);
if (mem == NULL)
{
perror("xmalloc");
printf("xmalloc: failed to allocate memory of size: %d\n", size);
}
return mem;
}
@ -58,7 +61,10 @@ void* xzalloc(size_t size)
mem = calloc(1, size);
if (mem == NULL)
{
perror("xzalloc");
printf("xzalloc: failed to allocate memory of size: %d\n", size);
}
return mem;
}
@ -76,6 +82,12 @@ void* xrealloc(void* ptr, size_t size)
if (size < 1)
size = 1;
if (ptr == NULL)
{
printf("xrealloc: null pointer given\n");
return NULL;
}
mem = realloc(ptr, size);
if (mem == NULL)

View File

@ -51,6 +51,16 @@ void xf_signal_event(xfEventQueue* event_queue)
printf("xf_signal_event: error\n");
}
void xf_set_event(xfEventQueue* event_queue)
{
int length;
length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4)
printf("xf_set_event: error\n");
}
void xf_clear_event(xfEventQueue* event_queue)
{
int length;
@ -64,6 +74,86 @@ void xf_clear_event(xfEventQueue* event_queue)
}
}
void xf_event_push(xfEventQueue* event_queue, xfEvent* event)
{
printf("xf_event_push lock\n");
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count >= event_queue->size)
{
event_queue->size = event_queue->size * 2;
event_queue->events = xrealloc((void*) event_queue->events, event_queue->size);
}
event_queue->events[(event_queue->count)++] = event;
xf_set_event(event_queue);
pthread_mutex_unlock(&(event_queue->mutex));
printf("xf_event_push unlock\n");
}
xfEvent* xf_event_peek(xfEventQueue* event_queue)
{
xfEvent* event;
printf("xf_event_peek lock\n");
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1)
event = NULL;
else
event = event_queue->events[0];
pthread_mutex_unlock(&(event_queue->mutex));
printf("xf_event_peek unlock\n");
return event;
}
xfEvent* xf_event_pop(xfEventQueue* event_queue)
{
int i;
xfEvent* event;
printf("xf_event_pop lock\n");
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1)
return NULL;
event = event_queue->events[0];
(event_queue->count)--;
for (i = 0; i < event_queue->count; i++)
event_queue->events[i] = event_queue->events[i + 1];
pthread_mutex_unlock(&(event_queue->mutex));
printf("xf_event_pop unlock\n");
return event;
}
xfEventRegion* xf_event_region_new(int x, int y, int width, int height)
{
xfEventRegion* event_region = xnew(xfEventRegion);
if (event_region != NULL)
{
event_region->x = x;
event_region->y = y;
event_region->width = width;
event_region->height = height;
}
return event_region;
}
void xf_event_region_free(xfEventRegion* event_region)
{
xfree(event_region);
}
xfEventQueue* xf_event_queue_new()
{
xfEventQueue* event_queue = xnew(xfEventQueue);
@ -79,6 +169,8 @@ xfEventQueue* xf_event_queue_new()
if (pipe(event_queue->pipe_fd) < 0)
printf("xf_event_queue_new: pipe failed\n");
pthread_mutex_init(&(event_queue->mutex), NULL);
}
return event_queue;
@ -97,4 +189,6 @@ void xf_event_queue_free(xfEventQueue* event_queue)
close(event_queue->pipe_fd[1]);
event_queue->pipe_fd[1] = -1;
}
pthread_mutex_destroy(&(event_queue->mutex));
}

View File

@ -45,6 +45,7 @@ struct xf_event_queue
int count;
int pipe_fd[2];
xfEvent** events;
pthread_mutex_t mutex;
};
struct xf_event_region
@ -57,9 +58,12 @@ struct xf_event_region
int height;
};
int xf_is_event_set(xfEventQueue* event_queue);
void xf_signal_event(xfEventQueue* event_queue);
void xf_clear_event(xfEventQueue* event_queue);
void xf_event_push(xfEventQueue* event_queue, xfEvent* event);
xfEvent* xf_event_peek(xfEventQueue* event_queue);
xfEvent* xf_event_pop(xfEventQueue* event_queue);
xfEventRegion* xf_event_region_new(int x, int y, int width, int height);
void xf_event_region_free(xfEventRegion* event_region);
xfEventQueue* xf_event_queue_new();
void xf_event_queue_free(xfEventQueue* event_queue);

View File

@ -298,18 +298,6 @@ void xf_peer_init(freerdp_peer* client)
xfp->thread = 0;
xfp->activations = 0;
xfp->stopwatch = stopwatch_create();
xfp->hdc = gdi_GetDC();
xfp->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND));
xfp->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);
xfp->hdc->hwnd->invalid->null = 1;
xfp->hdc->hwnd->count = 32;
xfp->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * xfp->hdc->hwnd->count);
xfp->hdc->hwnd->ninvalid = 0;
pthread_mutex_init(&(xfp->mutex), NULL);
}
@ -324,12 +312,12 @@ void* xf_monitor_graphics(void* param)
{
xfInfo* xfi;
XEvent xevent;
uint32 sec, usec;
XRectangle region;
xfPeerContext* xfp;
freerdp_peer* client;
int x, y, width, height;
XDamageNotifyEvent* notify;
xfEventRegion* event_region;
client = (freerdp_peer*) param;
xfp = (xfPeerContext*) client->context;
@ -339,8 +327,6 @@ void* xf_monitor_graphics(void* param)
pthread_detach(pthread_self());
stopwatch_start(xfp->stopwatch);
while (1)
{
pthread_mutex_lock(&(xfp->mutex));
@ -369,35 +355,12 @@ void* xf_monitor_graphics(void* param)
XDamageSubtract(xfi->display, xfi->xdamage, xfi->xdamage_region, None);
#endif
gdi_InvalidateRegion(xfp->hdc, x, y, width, height);
stopwatch_stop(xfp->stopwatch);
stopwatch_get_elapsed_time_in_useconds(xfp->stopwatch, &sec, &usec);
if ((sec > 0) || (usec > 30))
break;
event_region = xf_event_region_new(x, y, width, height);
xf_event_push(xfp->event_queue, (xfEvent*) event_region);
}
}
stopwatch_stop(xfp->stopwatch);
stopwatch_get_elapsed_time_in_useconds(xfp->stopwatch, &sec, &usec);
if ((sec > 0) || (usec > 30))
{
HGDI_RGN region;
stopwatch_reset(xfp->stopwatch);
stopwatch_start(xfp->stopwatch);
region = xfp->hdc->hwnd->invalid;
pthread_mutex_unlock(&(xfp->mutex));
xf_signal_event(xfp->event_queue);
}
else
{
pthread_mutex_unlock(&(xfp->mutex));
}
pthread_mutex_unlock(&(xfp->mutex));
freerdp_usleep(30);
}
@ -570,6 +533,7 @@ boolean xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
boolean xf_peer_check_fds(freerdp_peer* client)
{
xfInfo* xfi;
xfEvent* event;
xfPeerContext* xfp;
xfp = (xfPeerContext*) client->context;
@ -578,19 +542,16 @@ boolean xf_peer_check_fds(freerdp_peer* client)
if (xfp->activated == false)
return true;
if (xf_is_event_set(xfp->event_queue))
event = xf_event_peek(xfp->event_queue);
if (event != NULL)
{
HGDI_RGN region;
xf_clear_event(xfp->event_queue);
region = xfp->hdc->hwnd->invalid;
if (region->null)
return true;
xf_peer_rfx_update(client, region->x, region->y, region->w, region->h);
region->null = true;
if (event->type == XF_EVENT_TYPE_REGION)
{
xfEventRegion* region = (xfEventRegion*) xf_event_pop(xfp->event_queue);
xf_peer_rfx_update(client, region->x, region->y, region->width, region->height);
xf_event_region_free(region);
}
}
return true;

View File

@ -36,7 +36,6 @@ struct xf_peer_context
{
rdpContext _p;
HGDI_DC hdc;
STREAM* s;
xfInfo* info;
boolean activated;
@ -44,7 +43,6 @@ struct xf_peer_context
uint8* capture_buffer;
pthread_t thread;
int activations;
STOPWATCH* stopwatch;
pthread_mutex_t mutex;
xfEventQueue* event_queue;
};