xfreerdp: improve asynchronicity

This commit is contained in:
Marc-André Moreau 2013-02-09 17:13:53 -05:00
parent afbf067dc5
commit 4269ac5c14
10 changed files with 136 additions and 89 deletions

View File

@ -725,7 +725,8 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
status = xf_GetWindowProperty(xfi, event->xproperty.window,
xfi->WM_STATE, 1, &nitems, &bytes, &prop);
if (status != TRUE) {
if (status != TRUE)
{
DEBUG_X11_LMS("No return WM_STATE, window is not minimized");
}
else

View File

@ -267,11 +267,11 @@ void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
CopyMemory(xfi->clrconv->palette, palette, sizeof(rdpPalette));
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
@ -279,7 +279,7 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
XRectangle clip;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
if (bounds != NULL)
{
@ -294,14 +294,14 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
XSetClipMask(xfi->display, xfi->gc, None);
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop));
@ -323,7 +323,7 @@ void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
@ -335,7 +335,7 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
@ -419,14 +419,14 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_set_rop3(xfi, gdi_rop3_code(scrblt->bRop));
@ -457,7 +457,7 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
@ -466,7 +466,7 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
color = freerdp_color_convert_var(opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -490,7 +490,7 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
opaque_rect->nWidth, opaque_rect->nHeight);
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
@ -501,7 +501,7 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -529,7 +529,7 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
}
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
@ -543,7 +543,7 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_set_rop2(xfi, line_to->bRop2);
color = freerdp_color_convert_var(line_to->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -579,7 +579,7 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
@ -595,7 +595,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_set_rop2(xfi, polyline->bRop2);
color = freerdp_color_convert_var(polyline->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -646,7 +646,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
@ -654,7 +654,7 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
xfBitmap* bitmap;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
bitmap = (xfBitmap*) memblt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));
@ -677,7 +677,7 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
@ -690,7 +690,7 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
brush = &mem3blt->brush;
bitmap = (xfBitmap*) mem3blt->bitmap;
@ -756,7 +756,7 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
@ -766,7 +766,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
UINT32 brush_color;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_set_rop2(xfi, polygon_sc->bRop2);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -813,7 +813,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
@ -826,7 +826,7 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
UINT32 backColor;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
brush = &(polygon_cb->brush);
xf_set_rop2(xfi, polygon_cb->bRop2);
@ -920,7 +920,7 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
@ -941,7 +941,7 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
switch (surface_frame_marker->frameAction)
{
@ -974,7 +974,7 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
break;
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
static void xf_gdi_surface_update_frame(xfInfo* xfi, UINT16 tx, UINT16 ty, UINT16 width, UINT16 height)
@ -1020,7 +1020,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
{
@ -1125,7 +1125,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
printf("Unsupported codecID %d\n", surface_bits_command->codecID);
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_gdi_register_update_callbacks(rdpUpdate* update)

View File

@ -127,12 +127,12 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
else
{
@ -146,7 +146,7 @@ void xf_sw_end_paint(rdpContext* context)
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
for (i = 0; i < ninvalid; i++)
{
@ -161,7 +161,7 @@ void xf_sw_end_paint(rdpContext* context)
XFlush(xfi->display);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
}
else
@ -174,11 +174,11 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
}
@ -190,7 +190,7 @@ void xf_sw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
if (xfi->fullscreen != TRUE)
{
@ -206,7 +206,7 @@ void xf_sw_desktop_resize(rdpContext* context)
}
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
void xf_hw_begin_paint(rdpContext* context)
@ -236,11 +236,11 @@ void xf_hw_end_paint(rdpContext* context)
w = xfi->hdc->hwnd->invalid->w;
h = xfi->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
}
@ -253,7 +253,7 @@ void xf_hw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
if (xfi->fullscreen != TRUE)
{
@ -284,7 +284,7 @@ void xf_hw_desktop_resize(rdpContext* context)
XFillRectangle(xfi->display, xfi->drawable, xfi->gc, 0, 0, xfi->width, xfi->height);
}
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
}
BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
@ -309,11 +309,11 @@ BOOL xf_process_x_events(freerdp* instance)
while (pending_status)
{
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
pending_status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
if (pending_status)
{
@ -391,6 +391,18 @@ void xf_toggle_fullscreen(xfInfo* xfi)
XFreePixmap(xfi->display, contents);
}
void xf_lock_x11(xfInfo* xfi)
{
if (!xfi->UseXThreads)
WaitForSingleObject(xfi->mutex, INFINITE);
}
void xf_unlock_x11(xfInfo* xfi)
{
if (!xfi->UseXThreads)
ReleaseMutex(xfi->mutex);
}
BOOL xf_get_pixmap_info(xfInfo* xfi)
{
int i;
@ -608,8 +620,16 @@ BOOL xf_pre_connect(freerdp* instance)
return TRUE;
}
if (!XInitThreads())
printf("warning: XInitThreads() failure\n");
xfi->UseXThreads = FALSE;
if (xfi->UseXThreads)
{
if (!XInitThreads())
{
printf("warning: XInitThreads() failure\n");
xfi->UseXThreads = FALSE;
}
}
xfi->display = XOpenDisplay(NULL);
@ -1058,7 +1078,7 @@ void* xf_update_thread(void* arg)
while (MessageQueue_Wait(queue))
{
if (MessageQueue_Peek(queue, &message, TRUE))
while (MessageQueue_Peek(queue, &message, TRUE))
{
if (!freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message))
break;
@ -1078,29 +1098,28 @@ void* xf_input_thread(void* arg)
xfi = ((xfContext*) instance->context)->xfi;
event = CreateFileDescriptorEvent(NULL, TRUE, FALSE, xfi->xfds);
event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfi->xfds);
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
if (status)
while (status > 0)
{
ZeroMemory(&xevent, sizeof(xevent));
WaitForSingleObject(xfi->mutex, INFINITE);
xf_lock_x11(xfi);
XNextEvent(xfi->display, &xevent);
status = xf_event_process(instance, &xevent);
ReleaseMutex(xfi->mutex);
xf_unlock_x11(xfi);
if (!status)
break;
status--;
}
}
@ -1202,6 +1221,9 @@ int xfreerdp_run(freerdp* instance)
if (async_input)
{
/**
* FIXME: the input event file descriptor doesn't seem to work well with select(), why?
*/
input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
fd_input_event = GetEventFileDescriptor(input_event);
@ -1237,19 +1259,19 @@ int xfreerdp_run(freerdp* instance)
}
}
if (!async_input)
{
//if (!async_input)
//{
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
}
else
{
rfds[rcount++] = (void*) (long) fd_input_event;
}
//}
//else
//{
// rfds[rcount++] = (void*) (long) fd_input_event;
//}
max_fds = 0;
FD_ZERO(&rfds_set);
@ -1268,14 +1290,14 @@ int xfreerdp_run(freerdp* instance)
if (max_fds == 0)
break;
timeout.tv_sec = 1;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
select_status = select(max_fds + 1, &rfds_set, &wfds_set, NULL, &timeout);
select_status = select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL);
if (select_status == 0)
{
continue;
continue; /* select timeout */
}
else if (select_status == -1)
{
@ -1315,7 +1337,8 @@ int xfreerdp_run(freerdp* instance)
}
else
{
freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE);
//if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
}

View File

@ -115,6 +115,7 @@ struct xf_info
HCLRCONV clrconv;
Window parent_window;
HANDLE mutex;
BOOL UseXThreads;
HGDI_DC hdc;
BOOL sw_gdi;
@ -214,6 +215,9 @@ enum XF_EXIT_CODE
XF_EXIT_UNKNOWN = 255,
};
void xf_lock_x11(xfInfo* xfi);
void xf_unlock_x11(xfInfo* xfi);
#ifdef WITH_DEBUG_X11
#define DEBUG_X11(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__)
#else

View File

@ -1865,23 +1865,22 @@ int input_message_queue_process_message(rdpInput* input, wMessage* message)
int input_message_queue_process_pending_messages(rdpInput* input)
{
int count;
int status;
wMessage message;
wMessageQueue* queue;
count = 0;
queue = input->queue;
while (1)
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = MessageQueue_Peek(queue, &message, TRUE);
if (!status)
break;
status = input_message_queue_process_message(input, &message);
if (!status)
break;
count++;
}
return 0;

View File

@ -109,6 +109,8 @@ BOOL tls_connect(rdpTls* tls)
return FALSE;
}
//SSL_CTX_set_mode(tls->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);
/**
* SSL_OP_NO_COMPRESSION:
*
@ -390,8 +392,8 @@ int tls_write(rdpTls* tls, BYTE* data, int length)
{
error = SSL_get_error(tls->ssl, status);
//printf("tls_write: length: %d status: %d error: 0x%08X\n",
// length, status, error);
printf("tls_write: length: %d status: %d error: 0x%08X\n",
length, status, error);
switch (error)
{

View File

@ -277,6 +277,7 @@ typedef struct _wMessageQueue wMessageQueue;
WINPR_API HANDLE MessageQueue_Event(wMessageQueue* queue);
WINPR_API BOOL MessageQueue_Wait(wMessageQueue* queue);
WINPR_API int MessageQueue_Size(wMessageQueue* queue);
WINPR_API void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message);
WINPR_API void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam);

View File

@ -130,11 +130,13 @@ BOOL SetEvent(HANDLE hEvent)
#ifdef HAVE_EVENTFD_H
eventfd_t val = 1;
do
{
length = eventfd_write(event->pipe_fd[0], val);
}
while(length < 0 && errno == EINTR);
while ((length < 0) && (errno == EINTR));
status = (length == 0) ? TRUE : FALSE;
#else
if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
@ -176,15 +178,17 @@ BOOL ResetEvent(HANDLE hEvent)
{
#ifdef HAVE_EVENTFD_H
eventfd_t value;
do
{
length = eventfd_read(event->pipe_fd[0], &value);
}
while(length < 0 && errno == EINTR);
while ((length < 0) && (errno == EINTR));
status = (length > 0) ? TRUE : FALSE;
#else
length = read(event->pipe_fd[0], &length, 1);
if (length == 1)
status = TRUE;
@ -214,11 +218,6 @@ HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL
event->bAttached = TRUE;
event->bManualReset = bManualReset;
if (!event->bManualReset)
{
printf("CreateFileDescriptorEventW: auto-reset events not yet implemented\n");
}
event->pipe_fd[0] = FileDescriptor;
event->pipe_fd[1] = -1;

View File

@ -43,6 +43,15 @@ HANDLE MessageQueue_Event(wMessageQueue* queue)
return queue->event;
}
/**
* Gets the queue size
*/
int MessageQueue_Size(wMessageQueue* queue)
{
return queue->size;
}
/**
* Methods
*/
@ -73,7 +82,7 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
queue->array = (wMessage*) realloc(queue->array, sizeof(wMessage) * queue->capacity);
ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(wMessage));
if (queue->tail < (old_capacity - 1))
if (queue->tail < old_capacity)
{
CopyMemory(&(queue->array[old_capacity]), queue->array, queue->tail * sizeof(wMessage));
queue->tail += old_capacity;
@ -82,9 +91,11 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
CopyMemory(&(queue->array[queue->tail]), message, sizeof(wMessage));
queue->tail = (queue->tail + 1) % queue->capacity;
queue->size++;
SetEvent(queue->event);
if (queue->size == 0)
SetEvent(queue->event);
queue->size++;
ReleaseMutex(queue->mutex);
}
@ -120,14 +131,15 @@ int MessageQueue_Get(wMessageQueue* queue, wMessage* message)
CopyMemory(message, &(queue->array[queue->head]), sizeof(wMessage));
ZeroMemory(&(queue->array[queue->head]), sizeof(wMessage));
queue->head = (queue->head + 1) % queue->capacity;
if (queue->size == 1)
ResetEvent(queue->event);
queue->size--;
status = (message->id != WMQ_QUIT) ? 1 : 0;
}
if (queue->size < 1)
ResetEvent(queue->event);
ReleaseMutex(queue->mutex);
return status;
@ -148,6 +160,10 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove)
{
ZeroMemory(&(queue->array[queue->head]), sizeof(wMessage));
queue->head = (queue->head + 1) % queue->capacity;
if (queue->size == 1)
ResetEvent(queue->event);
queue->size--;
}
}
@ -175,6 +191,7 @@ wMessageQueue* MessageQueue_New()
queue->capacity = 32;
queue->array = (wMessage*) malloc(sizeof(wMessage) * queue->capacity);
ZeroMemory(queue->array, sizeof(wMessage) * queue->capacity);
queue->mutex = CreateMutex(NULL, FALSE, NULL);
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);

View File

@ -148,7 +148,7 @@ void Queue_Enqueue(wQueue* queue, void* obj)
queue->array = (void**) realloc(queue->array, sizeof(void*) * queue->capacity);
ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(void*));
if (queue->tail < (old_capacity - 1))
if (queue->tail < old_capacity)
{
CopyMemory(&(queue->array[old_capacity]), queue->array, queue->tail * sizeof(void*));
queue->tail += old_capacity;
@ -241,6 +241,7 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
queue->growthFactor = growthFactor;
queue->array = (void**) malloc(sizeof(void*) * queue->capacity);
ZeroMemory(queue->array, sizeof(void*) * queue->capacity);
queue->mutex = CreateMutex(NULL, FALSE, NULL);
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);