mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
Cleaned up collections:
ArrayList, MessageQueue, Queue, PubSub, BipBuffer ObjectPool and BufferPool
This commit is contained in:
parent
96bb569674
commit
6e3c00725a
@ -42,7 +42,6 @@ static void dvcman_wtslistener_free(DVCMAN_LISTENER* listener)
|
||||
{
|
||||
if (listener)
|
||||
free(listener->channel_name);
|
||||
|
||||
free(listener);
|
||||
}
|
||||
|
||||
@ -394,7 +393,6 @@ static void dvcman_clear(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pCha
|
||||
ArrayList_Clear(dvcman->plugin_names);
|
||||
ArrayList_Clear(dvcman->listeners);
|
||||
}
|
||||
|
||||
static void dvcman_free(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||
@ -1436,7 +1434,7 @@ static void drdynvc_queue_object_free(void* obj)
|
||||
static UINT drdynvc_virtual_channel_event_initialized(drdynvcPlugin* drdynvc, LPVOID pData,
|
||||
UINT32 dataLength)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wObject* obj;
|
||||
WINPR_UNUSED(pData);
|
||||
WINPR_UNUSED(dataLength);
|
||||
|
||||
@ -1447,17 +1445,18 @@ static UINT drdynvc_virtual_channel_event_initialized(drdynvcPlugin* drdynvc, LP
|
||||
|
||||
if (!drdynvc->queue)
|
||||
{
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_New failed!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
drdynvc->queue->object.fnObjectFree = drdynvc_queue_object_free;
|
||||
obj = MessageQueue_Object(drdynvc->queue);
|
||||
if (!obj)
|
||||
goto error;
|
||||
obj->fnObjectFree = drdynvc_queue_object_free;
|
||||
drdynvc->channel_mgr = dvcman_new(drdynvc);
|
||||
|
||||
if (!drdynvc->channel_mgr)
|
||||
{
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_new failed!");
|
||||
goto error;
|
||||
}
|
||||
@ -1562,7 +1561,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
|
||||
|
||||
CloseHandle(drdynvc->thread);
|
||||
drdynvc->thread = NULL;
|
||||
|
||||
status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle,
|
||||
drdynvc->OpenHandle);
|
||||
|
||||
@ -1603,7 +1601,6 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
|
||||
dvcman_free(drdynvc, drdynvc->channel_mgr);
|
||||
drdynvc->channel_mgr = NULL;
|
||||
}
|
||||
|
||||
drdynvc->InitHandle = 0;
|
||||
free(drdynvc->context);
|
||||
free(drdynvc);
|
||||
|
@ -1661,6 +1661,7 @@ static void queue_free(void* obj)
|
||||
static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pData,
|
||||
UINT32 dataLength)
|
||||
{
|
||||
wObject* obj;
|
||||
UINT32 status;
|
||||
status = rdpdr->channelEntryPoints.pVirtualChannelOpenEx(rdpdr->InitHandle, &rdpdr->OpenHandle,
|
||||
rdpdr->channelDef.name,
|
||||
@ -1681,7 +1682,10 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
rdpdr->queue->object.fnObjectFree = queue_free;
|
||||
obj = MessageQueue_Object(rdpdr->queue);
|
||||
if (!obj)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
obj->fnObjectFree = queue_free;
|
||||
|
||||
if (!(rdpdr->thread =
|
||||
CreateThread(NULL, 0, rdpdr_virtual_channel_client_thread, (void*)rdpdr, 0, NULL)))
|
||||
|
@ -332,13 +332,14 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
|
||||
// puts a buffer of size samples to the device
|
||||
int android_AudioOut(OPENSL_STREAM* p, const short* buffer, int size)
|
||||
{
|
||||
HANDLE ev;
|
||||
assert(p);
|
||||
assert(buffer);
|
||||
assert(size > 0);
|
||||
|
||||
ev = Queue_Event(p->queue);
|
||||
/* Assure, that the queue is not full. */
|
||||
if (p->queuesize <= Queue_Count(p->queue) &&
|
||||
WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED)
|
||||
if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(ev, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
DEBUG_SND("WaitForSingleObject failed!");
|
||||
return -1;
|
||||
|
@ -101,9 +101,9 @@ static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr,
|
||||
static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize,
|
||||
ndr_ptr_t type)
|
||||
{
|
||||
size_t len, offset, len2;
|
||||
size_t len = 0, offset, len2;
|
||||
void* r;
|
||||
size_t required;
|
||||
size_t required = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -346,6 +346,7 @@ finally:
|
||||
TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid,
|
||||
IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
wObject* obj;
|
||||
TSMF_PRESENTATION* presentation;
|
||||
|
||||
if (!guid || !pChannelCallback)
|
||||
@ -367,7 +368,10 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid,
|
||||
if (!(presentation->stream_list = ArrayList_New(TRUE)))
|
||||
goto error_stream_list;
|
||||
|
||||
ArrayList_Object(presentation->stream_list)->fnObjectFree = _tsmf_stream_free;
|
||||
obj = ArrayList_Object(presentation->stream_list);
|
||||
if (!obj)
|
||||
goto error_add;
|
||||
obj->fnObjectFree = _tsmf_stream_free;
|
||||
|
||||
if (ArrayList_Add(presentation_list, presentation) < 0)
|
||||
goto error_add;
|
||||
@ -1206,6 +1210,7 @@ void tsmf_presentation_free(TSMF_PRESENTATION* presentation)
|
||||
TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
|
||||
rdpContext* rdpcontext)
|
||||
{
|
||||
wObject* obj;
|
||||
TSMF_STREAM* stream;
|
||||
stream = tsmf_stream_find_by_id(presentation, stream_id);
|
||||
|
||||
@ -1247,13 +1252,21 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
|
||||
if (!stream->sample_list)
|
||||
goto error_sample_list;
|
||||
|
||||
stream->sample_list->object.fnObjectFree = tsmf_sample_free;
|
||||
obj = Queue_Object(stream->sample_list);
|
||||
if (!obj)
|
||||
goto error_sample_ack_list;
|
||||
obj->fnObjectFree = tsmf_sample_free;
|
||||
|
||||
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
|
||||
|
||||
if (!stream->sample_ack_list)
|
||||
goto error_sample_ack_list;
|
||||
|
||||
stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free;
|
||||
obj = Queue_Object(stream->sample_ack_list);
|
||||
if (!obj)
|
||||
goto error_play_thread;
|
||||
obj->fnObjectFree = tsmf_sample_free;
|
||||
|
||||
stream->play_thread =
|
||||
CreateThread(NULL, 0, tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
|
||||
|
||||
@ -1529,6 +1542,7 @@ static void tsmf_signal_handler(int s)
|
||||
|
||||
BOOL tsmf_media_init(void)
|
||||
{
|
||||
wObject* obj;
|
||||
#ifndef _WIN32
|
||||
struct sigaction sigtrap;
|
||||
sigtrap.sa_handler = tsmf_signal_handler;
|
||||
@ -1545,7 +1559,10 @@ BOOL tsmf_media_init(void)
|
||||
if (!presentation_list)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_Object(presentation_list)->fnObjectFree = _tsmf_presentation_free;
|
||||
obj = ArrayList_Object(presentation_list);
|
||||
if (!obj)
|
||||
return FALSE;
|
||||
obj->fnObjectFree = _tsmf_presentation_free;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -903,6 +903,7 @@ static DWORD poll_thread(LPVOID lpThreadParameter)
|
||||
#endif
|
||||
UINT freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
wObject* obj;
|
||||
UINT rc;
|
||||
UINT status;
|
||||
UDEVMAN* udevman;
|
||||
@ -915,8 +916,11 @@ UINT freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS
|
||||
udevman->hotplug_vid_pids = ArrayList_New(TRUE);
|
||||
if (!udevman->hotplug_vid_pids)
|
||||
goto fail;
|
||||
ArrayList_Object(udevman->hotplug_vid_pids)->fnObjectFree = free;
|
||||
ArrayList_Object(udevman->hotplug_vid_pids)->fnObjectEquals = udevman_vid_pid_pair_equals;
|
||||
obj = ArrayList_Object(udevman->hotplug_vid_pids);
|
||||
if (!obj)
|
||||
goto fail;
|
||||
obj->fnObjectFree = free;
|
||||
obj->fnObjectEquals = udevman_vid_pid_pair_equals;
|
||||
|
||||
udevman->next_device_id = BASE_USBDEVICE_NUM;
|
||||
udevman->iface.plugin = pEntryPoints->plugin;
|
||||
|
@ -167,6 +167,7 @@ static const char* x11_event_string(int event)
|
||||
|
||||
BOOL xf_event_action_script_init(xfContext* xfc)
|
||||
{
|
||||
wObject* obj;
|
||||
char* xevent;
|
||||
FILE* actionScript;
|
||||
char buffer[1024] = { 0 };
|
||||
@ -176,7 +177,10 @@ BOOL xf_event_action_script_init(xfContext* xfc)
|
||||
if (!xfc->xevents)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_Object(xfc->xevents)->fnObjectFree = free;
|
||||
obj = ArrayList_Object(xfc->xevents);
|
||||
if (!obj)
|
||||
return FALSE;
|
||||
obj->fnObjectFree = free;
|
||||
sprintf_s(command, sizeof(command), "%s xevent", xfc->context.settings->ActionScript);
|
||||
actionScript = popen(command, "r");
|
||||
|
||||
|
@ -48,6 +48,7 @@ static BOOL ungrabKeyboardWithRightCtrl = TRUE;
|
||||
|
||||
static BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
{
|
||||
wObject* obj;
|
||||
FILE* keyScript;
|
||||
char* keyCombination;
|
||||
char buffer[1024] = { 0 };
|
||||
@ -62,7 +63,10 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
if (!xfc->keyCombinations)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free;
|
||||
obj = ArrayList_Object(xfc->keyCombinations);
|
||||
if (!obj)
|
||||
return FALSE;
|
||||
obj->fnObjectFree = free;
|
||||
sprintf_s(command, sizeof(command), "%s key", xfc->context.settings->ActionScript);
|
||||
keyScript = popen(command, "r");
|
||||
|
||||
|
@ -153,7 +153,7 @@ static void rfx_tile_init(void* obj)
|
||||
}
|
||||
}
|
||||
|
||||
static void* rfx_decoder_tile_new(void* val)
|
||||
static void* rfx_decoder_tile_new(const void* val)
|
||||
{
|
||||
RFX_TILE* tile = NULL;
|
||||
WINPR_UNUSED(val);
|
||||
@ -184,7 +184,7 @@ static void rfx_decoder_tile_free(void* obj)
|
||||
}
|
||||
}
|
||||
|
||||
static void* rfx_encoder_tile_new(void* val)
|
||||
static void* rfx_encoder_tile_new(const void* val)
|
||||
{
|
||||
WINPR_UNUSED(val);
|
||||
return calloc(1, sizeof(RFX_TILE));
|
||||
|
@ -137,6 +137,7 @@ static BOOL CALLBACK init_channel_handles_table(PINIT_ONCE once, PVOID param, PV
|
||||
|
||||
rdpChannels* freerdp_channels_new(freerdp* instance)
|
||||
{
|
||||
wObject* obj;
|
||||
rdpChannels* channels;
|
||||
channels = (rdpChannels*)calloc(1, sizeof(rdpChannels));
|
||||
|
||||
@ -147,7 +148,6 @@ rdpChannels* freerdp_channels_new(freerdp* instance)
|
||||
|
||||
if (!g_ChannelHandles)
|
||||
goto error;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&channels->channelsLock, 4000))
|
||||
goto error;
|
||||
|
||||
@ -157,7 +157,11 @@ rdpChannels* freerdp_channels_new(freerdp* instance)
|
||||
if (!channels->queue)
|
||||
goto error;
|
||||
|
||||
channels->queue->object.fnObjectFree = channel_queue_free;
|
||||
obj = MessageQueue_Object(channels->queue);
|
||||
if (!obj)
|
||||
goto error;
|
||||
obj->fnObjectFree = channel_queue_free;
|
||||
|
||||
return channels;
|
||||
error:
|
||||
freerdp_channels_free(channels);
|
||||
@ -584,7 +588,6 @@ static BOOL freerdp_channels_process_message(freerdp* instance, wMessage* messag
|
||||
freerdp_channels_process_message_free(message, CHANNEL_EVENT_WRITE_CANCELLED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
channel =
|
||||
freerdp_channels_find_channel_by_name(instance->context->rdp, pChannelOpenData->name);
|
||||
|
||||
@ -729,9 +732,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
||||
int index;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||
|
||||
MessageQueue_PostQuit(channels->queue, 0);
|
||||
|
||||
freerdp_channels_check_fds(channels, instance);
|
||||
|
||||
/* tell all libraries we are shutting down */
|
||||
@ -1019,6 +1020,7 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelCloseEx(LPVOID pInitHandle, DWORD op
|
||||
return CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
|
||||
pChannelOpenData = HashTable_GetItemValue(g_ChannelHandles, (void*)(UINT_PTR)openHandle);
|
||||
|
||||
if (!pChannelOpenData)
|
||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||
|
||||
|
@ -1041,6 +1041,7 @@ static BOOL rpc_client_resolve_gateway(rdpSettings* settings, char** host, UINT1
|
||||
|
||||
RpcClient* rpc_client_new(rdpContext* context, UINT32 max_recv_frag)
|
||||
{
|
||||
wObject* obj;
|
||||
RpcClient* client = (RpcClient*)calloc(1, sizeof(RpcClient));
|
||||
|
||||
if (!client)
|
||||
@ -1081,7 +1082,11 @@ RpcClient* rpc_client_new(rdpContext* context, UINT32 max_recv_frag)
|
||||
if (!client->ClientCallList)
|
||||
goto fail;
|
||||
|
||||
ArrayList_Object(client->ClientCallList)->fnObjectFree = rpc_array_client_call_free;
|
||||
obj = ArrayList_Object(client->ClientCallList);
|
||||
if (!obj)
|
||||
goto fail;
|
||||
|
||||
obj->fnObjectFree = rpc_array_client_call_free;
|
||||
return client;
|
||||
fail:
|
||||
rpc_client_free(client);
|
||||
|
@ -63,6 +63,65 @@ static const char* pf_modules_get_hook_type_string(PF_HOOK_TYPE result)
|
||||
return "HOOK_UNKNOWN";
|
||||
}
|
||||
|
||||
static BOOL pf_modules_proxy_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
PF_HOOK_TYPE type;
|
||||
proxyData* pdata;
|
||||
BOOL ok = FALSE;
|
||||
|
||||
type = va_arg(ap, PF_HOOK_TYPE);
|
||||
pdata = va_arg(ap, proxyData*);
|
||||
|
||||
WLog_VRB(TAG, "running hook %s.%s", plugin->name, pf_modules_get_hook_type_string(type));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case HOOK_TYPE_CLIENT_PRE_CONNECT:
|
||||
IFCALLRET(plugin->ClientPreConnect, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_POST_CONNECT:
|
||||
IFCALLRET(plugin->ClientPostConnect, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_LOGIN_FAILURE:
|
||||
IFCALLRET(plugin->ClientLoginFailure, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_END_PAINT:
|
||||
IFCALLRET(plugin->ClientEndPaint, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_POST_CONNECT:
|
||||
IFCALLRET(plugin->ServerPostConnect, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_CHANNELS_INIT:
|
||||
IFCALLRET(plugin->ServerChannelsInit, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_CHANNELS_FREE:
|
||||
IFCALLRET(plugin->ServerChannelsFree, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_SESSION_END:
|
||||
IFCALLRET(plugin->ServerSessionEnd, ok, pdata);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "invalid hook called");
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
WLog_INFO(TAG, "plugin %s, hook %s failed!", plugin->name,
|
||||
pf_modules_get_hook_type_string(type));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* runs all hooks of type `type`.
|
||||
*
|
||||
@ -71,61 +130,56 @@ static const char* pf_modules_get_hook_type_string(PF_HOOK_TYPE result)
|
||||
*/
|
||||
BOOL pf_modules_run_hook(PF_HOOK_TYPE type, proxyData* pdata)
|
||||
{
|
||||
BOOL ok = TRUE;
|
||||
int index;
|
||||
proxyPlugin* plugin;
|
||||
return ArrayList_ForEach(plugins_list, pf_modules_proxy_ArrayList_ForEachFkt, type, pdata);
|
||||
}
|
||||
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, index, plugin)
|
||||
static BOOL pf_modules_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
PF_HOOK_TYPE type;
|
||||
proxyData* pdata;
|
||||
void* param;
|
||||
BOOL result = FALSE;
|
||||
|
||||
type = va_arg(ap, PF_HOOK_TYPE);
|
||||
pdata = va_arg(ap, proxyData*);
|
||||
param = va_arg(ap, void*);
|
||||
|
||||
WLog_VRB(TAG, "[%s]: running filter: %s", __FUNCTION__, plugin->name);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
WLog_VRB(TAG, "running hook %s.%s", plugin->name, pf_modules_get_hook_type_string(type));
|
||||
case FILTER_TYPE_KEYBOARD:
|
||||
IFCALLRET(plugin->KeyboardEvent, result, pdata, param);
|
||||
break;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case HOOK_TYPE_CLIENT_PRE_CONNECT:
|
||||
IFCALLRET(plugin->ClientPreConnect, ok, pdata);
|
||||
break;
|
||||
case FILTER_TYPE_MOUSE:
|
||||
IFCALLRET(plugin->MouseEvent, result, pdata, param);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_POST_CONNECT:
|
||||
IFCALLRET(plugin->ClientPostConnect, ok, pdata);
|
||||
break;
|
||||
case FILTER_TYPE_CLIENT_PASSTHROUGH_CHANNEL_DATA:
|
||||
IFCALLRET(plugin->ClientChannelData, result, pdata, param);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_LOGIN_FAILURE:
|
||||
IFCALLRET(plugin->ClientLoginFailure, ok, pdata);
|
||||
break;
|
||||
case FILTER_TYPE_SERVER_PASSTHROUGH_CHANNEL_DATA:
|
||||
IFCALLRET(plugin->ServerChannelData, result, pdata, param);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_CLIENT_END_PAINT:
|
||||
IFCALLRET(plugin->ClientEndPaint, ok, pdata);
|
||||
break;
|
||||
case FILTER_TYPE_SERVER_FETCH_TARGET_ADDR:
|
||||
IFCALLRET(plugin->ServerFetchTargetAddr, result, pdata, param);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_POST_CONNECT:
|
||||
IFCALLRET(plugin->ServerPostConnect, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_CHANNELS_INIT:
|
||||
IFCALLRET(plugin->ServerChannelsInit, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_CHANNELS_FREE:
|
||||
IFCALLRET(plugin->ServerChannelsFree, ok, pdata);
|
||||
break;
|
||||
|
||||
case HOOK_TYPE_SERVER_SESSION_END:
|
||||
IFCALLRET(plugin->ServerSessionEnd, ok, pdata);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "invalid hook called");
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
WLog_INFO(TAG, "plugin %s, hook %s failed!", plugin->name,
|
||||
pf_modules_get_hook_type_string(type));
|
||||
return FALSE;
|
||||
}
|
||||
default:
|
||||
WLog_ERR(TAG, "invalid filter called");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (!result)
|
||||
{
|
||||
/* current filter return FALSE, no need to run other filters. */
|
||||
WLog_DBG(TAG, "plugin %s, filter type [%s] returned FALSE", plugin->name,
|
||||
pf_modules_get_filter_type_string(type));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -136,51 +190,8 @@ BOOL pf_modules_run_hook(PF_HOOK_TYPE type, proxyData* pdata)
|
||||
*/
|
||||
BOOL pf_modules_run_filter(PF_FILTER_TYPE type, proxyData* pdata, void* param)
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
int index;
|
||||
proxyPlugin* plugin;
|
||||
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, index, plugin)
|
||||
{
|
||||
WLog_VRB(TAG, "[%s]: running filter: %s", __FUNCTION__, plugin->name);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FILTER_TYPE_KEYBOARD:
|
||||
IFCALLRET(plugin->KeyboardEvent, result, pdata, param);
|
||||
break;
|
||||
|
||||
case FILTER_TYPE_MOUSE:
|
||||
IFCALLRET(plugin->MouseEvent, result, pdata, param);
|
||||
break;
|
||||
|
||||
case FILTER_TYPE_CLIENT_PASSTHROUGH_CHANNEL_DATA:
|
||||
IFCALLRET(plugin->ClientChannelData, result, pdata, param);
|
||||
break;
|
||||
|
||||
case FILTER_TYPE_SERVER_PASSTHROUGH_CHANNEL_DATA:
|
||||
IFCALLRET(plugin->ServerChannelData, result, pdata, param);
|
||||
break;
|
||||
|
||||
case FILTER_TYPE_SERVER_FETCH_TARGET_ADDR:
|
||||
IFCALLRET(plugin->ServerFetchTargetAddr, result, pdata, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "invalid filter called");
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
/* current filter return FALSE, no need to run other filters. */
|
||||
WLog_DBG(TAG, "plugin %s, filter type [%s] returned FALSE", plugin->name,
|
||||
pf_modules_get_filter_type_string(type));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* all filters returned TRUE */
|
||||
return TRUE;
|
||||
return ArrayList_ForEach(plugins_list, pf_modules_ArrayList_ForEachFkt, type, pdata, param);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -238,23 +249,30 @@ static void pf_modules_abort_connect(proxyData* pdata)
|
||||
proxy_data_abort_connect(pdata);
|
||||
}
|
||||
|
||||
static BOOL pf_modules_register_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
proxyPlugin* plugin_to_register = va_arg(ap, proxyPlugin*);
|
||||
|
||||
WINPR_UNUSED(index);
|
||||
|
||||
if (strcmp(plugin->name, plugin_to_register->name) == 0)
|
||||
{
|
||||
WLog_ERR(TAG, "can not register plugin '%s', it is already registered!", plugin->name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pf_modules_register_plugin(proxyPlugin* plugin_to_register)
|
||||
{
|
||||
int index;
|
||||
proxyPlugin* plugin;
|
||||
|
||||
if (!plugin_to_register)
|
||||
return FALSE;
|
||||
|
||||
/* make sure there's no other loaded plugin with the same name of `plugin_to_register`. */
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, index, plugin)
|
||||
{
|
||||
if (strcmp(plugin->name, plugin_to_register->name) == 0)
|
||||
{
|
||||
WLog_ERR(TAG, "can not register plugin '%s', it is already registered!", plugin->name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!ArrayList_ForEach(plugins_list, pf_modules_register_ArrayList_ForEachFkt,
|
||||
plugin_to_register))
|
||||
return FALSE;
|
||||
|
||||
if (ArrayList_Add(plugins_list, plugin_to_register) < 0)
|
||||
{
|
||||
@ -266,28 +284,43 @@ static BOOL pf_modules_register_plugin(proxyPlugin* plugin_to_register)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pf_modules_load_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
const char* plugin_name = va_arg(ap, const char*);
|
||||
|
||||
WINPR_UNUSED(index);
|
||||
WINPR_UNUSED(ap);
|
||||
|
||||
if (strcmp(plugin->name, plugin_name) == 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL pf_modules_is_plugin_loaded(const char* plugin_name)
|
||||
{
|
||||
int i;
|
||||
proxyPlugin* plugin;
|
||||
|
||||
if (plugins_list == NULL)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, i, plugin)
|
||||
{
|
||||
if (strcmp(plugin->name, plugin_name) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
return ArrayList_ForEach(plugins_list, pf_modules_load_ArrayList_ForEachFkt, plugin_name);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
static BOOL pf_modules_print_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
const char* plugin_name = va_arg(ap, const char*);
|
||||
|
||||
WINPR_UNUSED(index);
|
||||
WINPR_UNUSED(ap);
|
||||
|
||||
WLog_INFO(TAG, "\tName: %s", plugin->name);
|
||||
WLog_INFO(TAG, "\tDescription: %s", plugin->description);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void pf_modules_list_loaded_plugins(void)
|
||||
{
|
||||
size_t count;
|
||||
int i;
|
||||
proxyPlugin* plugin;
|
||||
|
||||
if (plugins_list == NULL)
|
||||
return;
|
||||
@ -297,12 +330,7 @@ void pf_modules_list_loaded_plugins(void)
|
||||
if (count > 0)
|
||||
WLog_INFO(TAG, "Loaded plugins:");
|
||||
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, i, plugin)
|
||||
{
|
||||
|
||||
WLog_INFO(TAG, "\tName: %s", plugin->name);
|
||||
WLog_INFO(TAG, "\tDescription: %s", plugin->description);
|
||||
}
|
||||
ArrayList_ForEach(plugins_list, pf_modules_print_ArrayList_ForEachFkt);
|
||||
}
|
||||
|
||||
static proxyPluginsManager plugins_manager = { pf_modules_register_plugin,
|
||||
@ -398,34 +426,41 @@ error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL pf_modules_free_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
proxyPlugin* plugin = (proxyPlugin*)data;
|
||||
const char* plugin_name = va_arg(ap, const char*);
|
||||
|
||||
WINPR_UNUSED(index);
|
||||
WINPR_UNUSED(ap);
|
||||
|
||||
if (!IFCALLRESULT(TRUE, plugin->PluginUnload))
|
||||
WLog_WARN(TAG, "PluginUnload failed for plugin '%s'", plugin->name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pf_modules_free_handles_ArrayList_ForEachFkt(void* data, size_t index, va_list ap)
|
||||
{
|
||||
HANDLE handle = (HANDLE)data;
|
||||
|
||||
WINPR_UNUSED(index);
|
||||
WINPR_UNUSED(ap);
|
||||
if (handle)
|
||||
FreeLibrary(handle);
|
||||
}
|
||||
|
||||
void pf_modules_free(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (plugins_list)
|
||||
{
|
||||
proxyPlugin* plugin;
|
||||
|
||||
ArrayList_ForEach(plugins_list, proxyPlugin*, index, plugin)
|
||||
{
|
||||
if (!IFCALLRESULT(TRUE, plugin->PluginUnload))
|
||||
WLog_WARN(TAG, "PluginUnload failed for plugin '%s'", plugin->name);
|
||||
}
|
||||
|
||||
ArrayList_ForEach(plugins_list, pf_modules_free_ArrayList_ForEachFkt);
|
||||
ArrayList_Free(plugins_list);
|
||||
plugins_list = NULL;
|
||||
}
|
||||
|
||||
if (handles_list)
|
||||
{
|
||||
HANDLE handle;
|
||||
|
||||
ArrayList_ForEach(handles_list, HANDLE, index, handle)
|
||||
{
|
||||
if (handle)
|
||||
FreeLibrary(handle);
|
||||
};
|
||||
|
||||
ArrayList_ForEach(handles_list, pf_modules_free_handles_ArrayList_ForEachFkt);
|
||||
ArrayList_Free(handles_list);
|
||||
handles_list = NULL;
|
||||
}
|
||||
|
@ -582,6 +582,7 @@ static void pf_server_clients_list_client_free(void* obj)
|
||||
|
||||
proxyServer* pf_server_new(proxyConfig* config)
|
||||
{
|
||||
wObject* obj;
|
||||
proxyServer* server;
|
||||
|
||||
if (!config)
|
||||
@ -601,7 +602,8 @@ proxyServer* pf_server_new(proxyConfig* config)
|
||||
if (!server->clients)
|
||||
goto out;
|
||||
|
||||
server->clients->object.fnObjectFree = pf_server_clients_list_client_free;
|
||||
obj = ArrayList_Object(server->clients);
|
||||
obj->fnObjectFree = pf_server_clients_list_client_free;
|
||||
|
||||
server->waitGroup = CountdownEvent_New(0);
|
||||
if (!server->waitGroup)
|
||||
|
@ -125,10 +125,17 @@ void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
|
||||
|
||||
if (subsystem->MsgPipe)
|
||||
{
|
||||
wObject* obj1;
|
||||
wObject* obj2;
|
||||
/* Release resource in messages before free */
|
||||
subsystem->MsgPipe->In->object.fnObjectFree = shadow_subsystem_free_queued_message;
|
||||
obj1 = MessageQueue_Object(subsystem->MsgPipe->In);
|
||||
obj2 = MessageQueue_Object(subsystem->MsgPipe->Out);
|
||||
if (obj1)
|
||||
obj1->fnObjectFree = shadow_subsystem_free_queued_message;
|
||||
MessageQueue_Clear(subsystem->MsgPipe->In);
|
||||
subsystem->MsgPipe->Out->object.fnObjectFree = shadow_subsystem_free_queued_message;
|
||||
|
||||
if (obj2)
|
||||
obj2->fnObjectFree = shadow_subsystem_free_queued_message;
|
||||
MessageQueue_Clear(subsystem->MsgPipe->Out);
|
||||
MessagePipe_Free(subsystem->MsgPipe);
|
||||
subsystem->MsgPipe = NULL;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
@ -36,7 +37,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void* (*OBJECT_NEW_FN)(void* val);
|
||||
typedef void* (*OBJECT_NEW_FN)(const void* val);
|
||||
typedef void (*OBJECT_INIT_FN)(void* obj);
|
||||
typedef void (*OBJECT_UNINIT_FN)(void* obj);
|
||||
typedef void (*OBJECT_FREE_FN)(void* obj);
|
||||
@ -54,23 +55,6 @@ extern "C"
|
||||
|
||||
/* System.Collections.Queue */
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wQueue
|
||||
{
|
||||
int capacity;
|
||||
int growthFactor;
|
||||
BOOL synchronized;
|
||||
|
||||
int head;
|
||||
int tail;
|
||||
int size;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wQueue wQueue;
|
||||
|
||||
WINPR_API int Queue_Count(wQueue* queue);
|
||||
@ -80,11 +64,11 @@ extern "C"
|
||||
|
||||
WINPR_API HANDLE Queue_Event(wQueue* queue);
|
||||
|
||||
#define Queue_Object(_queue) (&_queue->object)
|
||||
WINPR_API wObject* Queue_Object(wQueue* queue);
|
||||
|
||||
WINPR_API void Queue_Clear(wQueue* queue);
|
||||
|
||||
WINPR_API BOOL Queue_Contains(wQueue* queue, void* obj);
|
||||
WINPR_API BOOL Queue_Contains(wQueue* queue, const void* obj);
|
||||
|
||||
WINPR_API BOOL Queue_Enqueue(wQueue* queue, void* obj);
|
||||
WINPR_API void* Queue_Dequeue(wQueue* queue);
|
||||
@ -116,25 +100,11 @@ extern "C"
|
||||
|
||||
/* System.Collections.ArrayList */
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wArrayList
|
||||
{
|
||||
int capacity;
|
||||
int growthFactor;
|
||||
BOOL synchronized;
|
||||
|
||||
int size;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wArrayList wArrayList;
|
||||
|
||||
WINPR_API int ArrayList_Capacity(wArrayList* arrayList);
|
||||
WINPR_API int ArrayList_Count(wArrayList* arrayList);
|
||||
WINPR_API int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems);
|
||||
WINPR_API size_t ArrayList_Capacity(wArrayList* arrayList);
|
||||
WINPR_API size_t ArrayList_Count(wArrayList* arrayList);
|
||||
WINPR_API size_t ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems);
|
||||
WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
|
||||
@ -142,28 +112,28 @@ extern "C"
|
||||
WINPR_API void ArrayList_Lock(wArrayList* arrayList);
|
||||
WINPR_API void ArrayList_Unlock(wArrayList* arrayList);
|
||||
|
||||
WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index);
|
||||
WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj);
|
||||
WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, size_t index);
|
||||
WINPR_API void ArrayList_SetItem(wArrayList* arrayList, size_t index, const void* obj);
|
||||
|
||||
#define ArrayList_Object(_arrayList) (&_arrayList->object)
|
||||
WINPR_API wObject* ArrayList_Object(wArrayList* arrayList);
|
||||
|
||||
#define ArrayList_ForEach(_lst, _type, index, value) \
|
||||
for (index = 0; \
|
||||
index < ArrayList_Count(_lst) && (value = (_type)ArrayList_GetItem(_lst, index)); \
|
||||
index++)
|
||||
typedef BOOL(ArrayList_ForEachFkt)(void* data, size_t index, va_list ap);
|
||||
|
||||
WINPR_API BOOL ArrayList_ForEach(wArrayList* arrayList, ArrayList_ForEachFkt fkt, ...);
|
||||
|
||||
WINPR_API void ArrayList_Clear(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj);
|
||||
WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, const void* obj);
|
||||
|
||||
WINPR_API int ArrayList_Add(wArrayList* arrayList, void* obj);
|
||||
WINPR_API BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj);
|
||||
WINPR_API BOOL ArrayList_Insert(wArrayList* arrayList, size_t index, const void* obj);
|
||||
|
||||
WINPR_API BOOL ArrayList_Remove(wArrayList* arrayList, void* obj);
|
||||
WINPR_API BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index);
|
||||
WINPR_API BOOL ArrayList_Remove(wArrayList* arrayList, const void* obj);
|
||||
WINPR_API BOOL ArrayList_RemoveAt(wArrayList* arrayList, size_t index);
|
||||
|
||||
WINPR_API int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count);
|
||||
WINPR_API int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex,
|
||||
int count);
|
||||
WINPR_API SSIZE_T ArrayList_IndexOf(wArrayList* arrayList, const void* obj, SSIZE_T startIndex,
|
||||
SSIZE_T count);
|
||||
WINPR_API SSIZE_T ArrayList_LastIndexOf(wArrayList* arrayList, const void* obj,
|
||||
SSIZE_T startIndex, SSIZE_T count);
|
||||
|
||||
WINPR_API wArrayList* ArrayList_New(BOOL synchronized);
|
||||
WINPR_API void ArrayList_Free(wArrayList* arrayList);
|
||||
@ -387,68 +357,27 @@ extern "C"
|
||||
|
||||
/* BufferPool */
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBufferPoolItem
|
||||
{
|
||||
int size;
|
||||
void* buffer;
|
||||
};
|
||||
typedef struct _wBufferPoolItem wBufferPoolItem;
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBufferPool
|
||||
{
|
||||
int fixedSize;
|
||||
DWORD alignment;
|
||||
BOOL synchronized;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
|
||||
int aSize;
|
||||
int aCapacity;
|
||||
wBufferPoolItem* aArray;
|
||||
|
||||
int uSize;
|
||||
int uCapacity;
|
||||
wBufferPoolItem* uArray;
|
||||
};
|
||||
typedef struct _wBufferPool wBufferPool;
|
||||
|
||||
WINPR_API int BufferPool_GetPoolSize(wBufferPool* pool);
|
||||
WINPR_API int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer);
|
||||
WINPR_API SSIZE_T BufferPool_GetPoolSize(wBufferPool* pool);
|
||||
WINPR_API SSIZE_T BufferPool_GetBufferSize(wBufferPool* pool, const void* buffer);
|
||||
|
||||
WINPR_API void* BufferPool_Take(wBufferPool* pool, int bufferSize);
|
||||
WINPR_API void* BufferPool_Take(wBufferPool* pool, SSIZE_T bufferSize);
|
||||
WINPR_API BOOL BufferPool_Return(wBufferPool* pool, void* buffer);
|
||||
WINPR_API void BufferPool_Clear(wBufferPool* pool);
|
||||
|
||||
WINPR_API wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment);
|
||||
WINPR_API wBufferPool* BufferPool_New(BOOL synchronized, SSIZE_T fixedSize, DWORD alignment);
|
||||
WINPR_API void BufferPool_Free(wBufferPool* pool);
|
||||
|
||||
/* ObjectPool */
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wObjectPool
|
||||
{
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
wObject object;
|
||||
BOOL synchronized;
|
||||
};
|
||||
typedef struct _wObjectPool wObjectPool;
|
||||
|
||||
WINPR_API void* ObjectPool_Take(wObjectPool* pool);
|
||||
WINPR_API void ObjectPool_Return(wObjectPool* pool, void* obj);
|
||||
WINPR_API void ObjectPool_Clear(wObjectPool* pool);
|
||||
|
||||
#define ObjectPool_Object(_pool) (&_pool->object)
|
||||
WINPR_API wObject* ObjectPool_Object(wObjectPool* pool);
|
||||
|
||||
WINPR_API wObjectPool* ObjectPool_New(BOOL synchronized);
|
||||
WINPR_API void ObjectPool_Free(wObjectPool* pool);
|
||||
@ -469,30 +398,16 @@ extern "C"
|
||||
MESSAGE_FREE_FN Free;
|
||||
};
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wMessageQueue
|
||||
{
|
||||
int head;
|
||||
int tail;
|
||||
int size;
|
||||
int capacity;
|
||||
BOOL closed;
|
||||
wMessage* array;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wMessageQueue wMessageQueue;
|
||||
|
||||
#define WMQ_QUIT 0xFFFFFFFF
|
||||
|
||||
WINPR_API wObject* MessageQueue_Object(wMessageQueue* queue);
|
||||
WINPR_API HANDLE MessageQueue_Event(wMessageQueue* queue);
|
||||
WINPR_API BOOL MessageQueue_Wait(wMessageQueue* queue);
|
||||
WINPR_API int MessageQueue_Size(wMessageQueue* queue);
|
||||
WINPR_API size_t MessageQueue_Size(wMessageQueue* queue);
|
||||
|
||||
WINPR_API BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message);
|
||||
WINPR_API BOOL MessageQueue_Dispatch(wMessageQueue* queue, const wMessage* message);
|
||||
WINPR_API BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam,
|
||||
void* lParam);
|
||||
WINPR_API BOOL MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode);
|
||||
@ -618,24 +533,13 @@ extern "C"
|
||||
|
||||
#define DEFINE_EVENT_ENTRY(_name) { #_name, { sizeof(_name##EventArgs), NULL }, 0, { NULL } },
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wPubSub
|
||||
{
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
|
||||
int size;
|
||||
int count;
|
||||
wEventType* events;
|
||||
};
|
||||
typedef struct _wPubSub wPubSub;
|
||||
|
||||
WINPR_API void PubSub_Lock(wPubSub* pubSub);
|
||||
WINPR_API void PubSub_Unlock(wPubSub* pubSub);
|
||||
|
||||
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
|
||||
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
|
||||
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, size_t* count);
|
||||
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, size_t count);
|
||||
WINPR_API wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName);
|
||||
|
||||
WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName,
|
||||
@ -650,28 +554,6 @@ extern "C"
|
||||
WINPR_API void PubSub_Free(wPubSub* pubSub);
|
||||
|
||||
/* BipBuffer */
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBipBlock
|
||||
{
|
||||
size_t index;
|
||||
size_t size;
|
||||
};
|
||||
typedef struct _wBipBlock wBipBlock;
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBipBuffer
|
||||
{
|
||||
size_t size;
|
||||
BYTE* buffer;
|
||||
size_t pageSize;
|
||||
wBipBlock blockA;
|
||||
wBipBlock blockB;
|
||||
wBipBlock readR;
|
||||
wBipBlock writeR;
|
||||
};
|
||||
typedef struct _wBipBuffer wBipBuffer;
|
||||
|
||||
WINPR_API BOOL BipBuffer_Grow(wBipBuffer* bb, size_t size);
|
||||
|
@ -659,6 +659,7 @@ static void* convert_filedescriptors_to_uri_list(wClipboard* clipboard, UINT32 f
|
||||
|
||||
static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
|
||||
{
|
||||
wObject* obj;
|
||||
UINT32 file_group_format_id;
|
||||
UINT32 local_file_format_id;
|
||||
file_group_format_id = ClipboardRegisterFormat(clipboard, "FileGroupDescriptorW");
|
||||
@ -672,7 +673,10 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
|
||||
if (!clipboard->localFiles)
|
||||
goto error;
|
||||
|
||||
ArrayList_Object(clipboard->localFiles)->fnObjectFree = free_posix_file;
|
||||
obj = ArrayList_Object(clipboard->localFiles);
|
||||
if (!obj)
|
||||
goto error;
|
||||
obj->fnObjectFree = free_posix_file;
|
||||
|
||||
if (!ClipboardRegisterSynthesizer(clipboard, local_file_format_id, file_group_format_id,
|
||||
convert_uri_list_to_filedescriptors))
|
||||
|
@ -106,6 +106,7 @@ static void threads_close(void* thread)
|
||||
static BOOL InitializeThreadpool(PTP_POOL pool)
|
||||
{
|
||||
int index;
|
||||
wObject* obj;
|
||||
HANDLE thread;
|
||||
|
||||
if (pool->Threads)
|
||||
@ -126,7 +127,8 @@ static BOOL InitializeThreadpool(PTP_POOL pool)
|
||||
if (!(pool->Threads = ArrayList_New(TRUE)))
|
||||
goto fail_thread_array;
|
||||
|
||||
pool->Threads->object.fnObjectFree = threads_close;
|
||||
obj = ArrayList_Object(pool->Threads);
|
||||
obj->fnObjectFree = threads_close;
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
|
@ -25,6 +25,19 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
struct _wArrayList
|
||||
{
|
||||
size_t capacity;
|
||||
size_t growthFactor;
|
||||
BOOL synchronized;
|
||||
|
||||
size_t size;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
|
||||
/**
|
||||
* C equivalent of the C# ArrayList Class:
|
||||
* http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx
|
||||
@ -38,7 +51,7 @@
|
||||
* Gets or sets the number of elements that the ArrayList can contain.
|
||||
*/
|
||||
|
||||
int ArrayList_Capacity(wArrayList* arrayList)
|
||||
size_t ArrayList_Capacity(wArrayList* arrayList)
|
||||
{
|
||||
return arrayList->capacity;
|
||||
}
|
||||
@ -47,7 +60,7 @@ int ArrayList_Capacity(wArrayList* arrayList)
|
||||
* Gets the number of elements actually contained in the ArrayList.
|
||||
*/
|
||||
|
||||
int ArrayList_Count(wArrayList* arrayList)
|
||||
size_t ArrayList_Count(wArrayList* arrayList)
|
||||
{
|
||||
return arrayList->size;
|
||||
}
|
||||
@ -56,7 +69,7 @@ int ArrayList_Count(wArrayList* arrayList)
|
||||
* Gets the internal list of items contained in the ArrayList.
|
||||
*/
|
||||
|
||||
int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems)
|
||||
size_t ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems)
|
||||
{
|
||||
*ppItems = (ULONG_PTR*)arrayList->array;
|
||||
return arrayList->size;
|
||||
@ -93,6 +106,12 @@ BOOL ArrayList_IsSynchronized(wArrayList* arrayList)
|
||||
* Lock access to the ArrayList
|
||||
*/
|
||||
|
||||
void ArrayList_Lock_Conditional(wArrayList* arrayList)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
void ArrayList_Lock(wArrayList* arrayList)
|
||||
{
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
@ -102,6 +121,12 @@ void ArrayList_Lock(wArrayList* arrayList)
|
||||
* Unlock access to the ArrayList
|
||||
*/
|
||||
|
||||
void ArrayList_Unlock_Conditional(wArrayList* arrayList)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
void ArrayList_Unlock(wArrayList* arrayList)
|
||||
{
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
@ -111,7 +136,7 @@ void ArrayList_Unlock(wArrayList* arrayList)
|
||||
* Gets the element at the specified index.
|
||||
*/
|
||||
|
||||
void* ArrayList_GetItem(wArrayList* arrayList, int index)
|
||||
void* ArrayList_GetItem(wArrayList* arrayList, size_t index)
|
||||
{
|
||||
void* obj = NULL;
|
||||
|
||||
@ -127,18 +152,43 @@ void* ArrayList_GetItem(wArrayList* arrayList, int index)
|
||||
* Sets the element at the specified index.
|
||||
*/
|
||||
|
||||
void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj)
|
||||
void ArrayList_SetItem(wArrayList* arrayList, size_t index, const void* obj)
|
||||
{
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
arrayList->array[index] = obj;
|
||||
if (arrayList->object.fnObjectNew)
|
||||
arrayList->array[index] = arrayList->object.fnObjectNew(obj);
|
||||
else
|
||||
arrayList->array[index] = (void*)obj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods
|
||||
*/
|
||||
static BOOL ArrayList_EnsureCapacity(wArrayList* arrayList, size_t count)
|
||||
{
|
||||
if (!arrayList)
|
||||
return FALSE;
|
||||
|
||||
if (arrayList->size + count > arrayList->capacity)
|
||||
{
|
||||
void** newArray;
|
||||
size_t newCapacity = arrayList->capacity * arrayList->growthFactor;
|
||||
if (newCapacity < arrayList->size + count)
|
||||
newCapacity = arrayList->size + count;
|
||||
|
||||
newArray = (void**)realloc(arrayList->array, sizeof(void*) * newCapacity);
|
||||
|
||||
if (!newArray)
|
||||
return FALSE;
|
||||
|
||||
arrayList->array = newArray;
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/**
|
||||
* Shift a section of the list.
|
||||
*/
|
||||
@ -147,18 +197,8 @@ static BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
if (arrayList->size + count > arrayList->capacity)
|
||||
{
|
||||
void** newArray;
|
||||
int newCapacity = arrayList->capacity * arrayList->growthFactor;
|
||||
newArray = (void**)realloc(arrayList->array, sizeof(void*) * newCapacity);
|
||||
|
||||
if (!newArray)
|
||||
return FALSE;
|
||||
|
||||
arrayList->array = newArray;
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
if (!ArrayList_EnsureCapacity(arrayList, count))
|
||||
return FALSE;
|
||||
|
||||
MoveMemory(&arrayList->array[index + count], &arrayList->array[index],
|
||||
(arrayList->size - index) * sizeof(void*));
|
||||
@ -166,7 +206,7 @@ static BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
int chunk = arrayList->size - index + count;
|
||||
INT64 chunk = arrayList->size - index + count;
|
||||
|
||||
if (chunk > 0)
|
||||
MoveMemory(&arrayList->array[index], &arrayList->array[index - count],
|
||||
@ -184,10 +224,9 @@ static BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
||||
|
||||
void ArrayList_Clear(wArrayList* arrayList)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -199,21 +238,19 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
|
||||
arrayList->size = 0;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an element is in the ArrayList.
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
||||
BOOL ArrayList_Contains(wArrayList* arrayList, const void* obj)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -223,8 +260,7 @@ BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
||||
break;
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -237,28 +273,16 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
if (arrayList->size + 1 > arrayList->capacity)
|
||||
{
|
||||
void** newArray;
|
||||
int newCapacity = arrayList->capacity * arrayList->growthFactor;
|
||||
newArray = (void**)realloc(arrayList->array, sizeof(void*) * newCapacity);
|
||||
if (!ArrayList_EnsureCapacity(arrayList, 1))
|
||||
goto out;
|
||||
|
||||
if (!newArray)
|
||||
goto out;
|
||||
|
||||
arrayList->array = newArray;
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
|
||||
arrayList->array[arrayList->size++] = obj;
|
||||
index = arrayList->size;
|
||||
index = arrayList->size++;
|
||||
ArrayList_SetItem(arrayList, index, obj);
|
||||
out:
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -267,12 +291,11 @@ out:
|
||||
* Inserts an element into the ArrayList at the specified index.
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
BOOL ArrayList_Insert(wArrayList* arrayList, size_t index, const void* obj)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -282,12 +305,11 @@ BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayList->array[index] = obj;
|
||||
ArrayList_SetItem(arrayList, index, obj);
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -296,14 +318,13 @@ BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
* Removes the first occurrence of a specific object from the ArrayList.
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
BOOL ArrayList_Remove(wArrayList* arrayList, const void* obj)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
BOOL found = FALSE;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -322,8 +343,7 @@ BOOL ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
ret = ArrayList_Shift(arrayList, index, -1);
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -332,12 +352,11 @@ BOOL ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
* Removes the element at the specified index of the ArrayList.
|
||||
*/
|
||||
|
||||
BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
BOOL ArrayList_RemoveAt(wArrayList* arrayList, size_t index)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -347,8 +366,7 @@ BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
ret = ArrayList_Shift(arrayList, index, -1);
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -366,21 +384,22 @@ BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
* the specified index.
|
||||
*/
|
||||
|
||||
int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count)
|
||||
SSIZE_T ArrayList_IndexOf(wArrayList* arrayList, const void* obj, SSIZE_T startIndex, SSIZE_T count)
|
||||
{
|
||||
int index;
|
||||
SSIZE_T index, sindex, cindex;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
sindex = (size_t)startIndex;
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
sindex = 0;
|
||||
|
||||
cindex = (size_t)count;
|
||||
if (count < 0)
|
||||
count = arrayList->size;
|
||||
cindex = arrayList->size;
|
||||
|
||||
for (index = startIndex; index < startIndex + count; index++)
|
||||
for (index = sindex; index < sindex + cindex; index++)
|
||||
{
|
||||
if (arrayList->object.fnObjectEquals(arrayList->array[index], obj))
|
||||
{
|
||||
@ -392,8 +411,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
if (!found)
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -411,23 +429,25 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
* the specified index.
|
||||
*/
|
||||
|
||||
int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int count)
|
||||
SSIZE_T ArrayList_LastIndexOf(wArrayList* arrayList, const void* obj, SSIZE_T startIndex,
|
||||
SSIZE_T count)
|
||||
{
|
||||
int index;
|
||||
SSIZE_T index, sindex, cindex;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
|
||||
sindex = (size_t)startIndex;
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
sindex = 0;
|
||||
|
||||
cindex = (size_t)count;
|
||||
if (count < 0)
|
||||
count = arrayList->size;
|
||||
cindex = arrayList->size;
|
||||
|
||||
for (index = startIndex + count - 1; index >= startIndex; index--)
|
||||
for (index = sindex + cindex; index > sindex; index--)
|
||||
{
|
||||
if (arrayList->object.fnObjectEquals(arrayList->array[index], obj))
|
||||
if (arrayList->object.fnObjectEquals(arrayList->array[index - 1], obj))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
@ -437,8 +457,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int
|
||||
if (!found)
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -448,12 +467,45 @@ static BOOL ArrayList_DefaultCompare(const void* objA, const void* objB)
|
||||
return objA == objB ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
wObject* ArrayList_Object(wArrayList* arrayList)
|
||||
{
|
||||
if (!arrayList)
|
||||
return NULL;
|
||||
return &arrayList->object;
|
||||
}
|
||||
|
||||
BOOL ArrayList_ForEach(wArrayList* arrayList, ArrayList_ForEachFkt fkt, ...)
|
||||
{
|
||||
size_t index, count;
|
||||
va_list ap;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if (!arrayList || !fkt)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_Lock_Conditional(arrayList);
|
||||
count = ArrayList_Count(arrayList);
|
||||
va_start(ap, (void*)fkt);
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
void* obj = ArrayList_GetItem(arrayList, index);
|
||||
if (!fkt(obj, index, ap))
|
||||
goto fail;
|
||||
}
|
||||
va_end(ap);
|
||||
rc = TRUE;
|
||||
fail:
|
||||
ArrayList_Unlock_Conditional(arrayList);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
|
||||
wArrayList* ArrayList_New(BOOL synchronized)
|
||||
{
|
||||
wObject* obj;
|
||||
wArrayList* arrayList = NULL;
|
||||
arrayList = (wArrayList*)calloc(1, sizeof(wArrayList));
|
||||
|
||||
@ -461,18 +513,18 @@ wArrayList* ArrayList_New(BOOL synchronized)
|
||||
return NULL;
|
||||
|
||||
arrayList->synchronized = synchronized;
|
||||
arrayList->capacity = 32;
|
||||
arrayList->growthFactor = 2;
|
||||
arrayList->object.fnObjectEquals = ArrayList_DefaultCompare;
|
||||
arrayList->array = (void**)calloc(arrayList->capacity, sizeof(void*));
|
||||
|
||||
if (!arrayList->array)
|
||||
goto out_free;
|
||||
obj = ArrayList_Object(arrayList);
|
||||
if (!obj)
|
||||
goto fail;
|
||||
obj->fnObjectEquals = ArrayList_DefaultCompare;
|
||||
if (!ArrayList_EnsureCapacity(arrayList, 32))
|
||||
goto fail;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000);
|
||||
return arrayList;
|
||||
out_free:
|
||||
free(arrayList);
|
||||
fail:
|
||||
ArrayList_Free(arrayList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -27,23 +27,46 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
struct _wBipBlock
|
||||
{
|
||||
size_t index;
|
||||
size_t size;
|
||||
};
|
||||
typedef struct _wBipBlock wBipBlock;
|
||||
|
||||
struct _wBipBuffer
|
||||
{
|
||||
size_t size;
|
||||
BYTE* buffer;
|
||||
size_t pageSize;
|
||||
wBipBlock blockA;
|
||||
wBipBlock blockB;
|
||||
wBipBlock readR;
|
||||
wBipBlock writeR;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Bip Buffer - The Circular Buffer with a Twist:
|
||||
* http://www.codeproject.com/Articles/3479/The-Bip-Buffer-The-Circular-Buffer-with-a-Twist
|
||||
*/
|
||||
|
||||
#define BipBlock_Clear(_bbl) _bbl.index = _bbl.size = 0
|
||||
static INLINE void BipBlock_Clear(wBipBlock* _bbl)
|
||||
{
|
||||
_bbl->index = _bbl->size = 0;
|
||||
}
|
||||
|
||||
#define BipBlock_Copy(_dst, _src) \
|
||||
_dst.index = _src.index; \
|
||||
_dst.size = _src.size
|
||||
static INLINE void BipBlock_Copy(wBipBlock* _dst, const wBipBlock* _src)
|
||||
{
|
||||
_dst->index = _src->index;
|
||||
_dst->size = _src->size;
|
||||
}
|
||||
|
||||
void BipBuffer_Clear(wBipBuffer* bb)
|
||||
{
|
||||
BipBlock_Clear(bb->blockA);
|
||||
BipBlock_Clear(bb->blockB);
|
||||
BipBlock_Clear(bb->readR);
|
||||
BipBlock_Clear(bb->writeR);
|
||||
BipBlock_Clear(&bb->blockA);
|
||||
BipBlock_Clear(&bb->blockB);
|
||||
BipBlock_Clear(&bb->readR);
|
||||
BipBlock_Clear(&bb->writeR);
|
||||
}
|
||||
|
||||
static BOOL BipBuffer_AllocBuffer(wBipBuffer* bb, size_t size)
|
||||
@ -198,7 +221,7 @@ void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
BipBlock_Clear(bb->writeR);
|
||||
BipBlock_Clear(&bb->writeR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -209,7 +232,7 @@ void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size)
|
||||
{
|
||||
bb->blockA.index = bb->writeR.index;
|
||||
bb->blockA.size = size;
|
||||
BipBlock_Clear(bb->writeR);
|
||||
BipBlock_Clear(&bb->writeR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -218,7 +241,7 @@ void BipBuffer_WriteCommit(wBipBuffer* bb, size_t size)
|
||||
else
|
||||
bb->blockB.size += size;
|
||||
|
||||
BipBlock_Clear(bb->writeR);
|
||||
BipBlock_Clear(&bb->writeR);
|
||||
}
|
||||
|
||||
SSIZE_T BipBuffer_Write(wBipBuffer* bb, const BYTE* data, size_t size)
|
||||
@ -332,8 +355,8 @@ void BipBuffer_ReadCommit(wBipBuffer* bb, size_t size)
|
||||
|
||||
if (size >= bb->blockA.size)
|
||||
{
|
||||
BipBlock_Copy(bb->blockA, bb->blockB);
|
||||
BipBlock_Clear(bb->blockB);
|
||||
BipBlock_Copy(&bb->blockA, &bb->blockB);
|
||||
BipBlock_Clear(&bb->blockB);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -25,6 +25,57 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBufferPoolItem
|
||||
{
|
||||
SSIZE_T size;
|
||||
void* buffer;
|
||||
};
|
||||
typedef struct _wBufferPoolItem wBufferPoolItem;
|
||||
|
||||
/* WARNING: Do not access structs directly, the API will be reworked
|
||||
* to make this opaque. */
|
||||
struct _wBufferPool
|
||||
{
|
||||
SSIZE_T fixedSize;
|
||||
DWORD alignment;
|
||||
BOOL synchronized;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
SSIZE_T size;
|
||||
SSIZE_T capacity;
|
||||
void** array;
|
||||
|
||||
SSIZE_T aSize;
|
||||
SSIZE_T aCapacity;
|
||||
wBufferPoolItem* aArray;
|
||||
|
||||
SSIZE_T uSize;
|
||||
SSIZE_T uCapacity;
|
||||
wBufferPoolItem* uArray;
|
||||
};
|
||||
|
||||
static BOOL BufferPool_Lock(wBufferPool* pool)
|
||||
{
|
||||
if (!pool)
|
||||
return FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL BufferPool_Unlock(wBufferPool* pool)
|
||||
{
|
||||
if (!pool)
|
||||
return FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* C equivalent of the C# BufferManager Class:
|
||||
* http://msdn.microsoft.com/en-us/library/ms405814.aspx
|
||||
@ -41,10 +92,14 @@ static BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
|
||||
if (pool->aSize + count > pool->aCapacity)
|
||||
{
|
||||
wBufferPoolItem* newArray;
|
||||
int newCapacity = pool->aCapacity * 2;
|
||||
SSIZE_T newCapacity = pool->aCapacity * 2;
|
||||
|
||||
newArray =
|
||||
(wBufferPoolItem*)realloc(pool->aArray, sizeof(wBufferPoolItem) * newCapacity);
|
||||
if (pool->alignment > 0)
|
||||
newArray = (wBufferPoolItem*)_aligned_realloc(
|
||||
pool->aArray, sizeof(wBufferPoolItem) * newCapacity, pool->alignment);
|
||||
else
|
||||
newArray =
|
||||
(wBufferPoolItem*)realloc(pool->aArray, sizeof(wBufferPoolItem) * newCapacity);
|
||||
if (!newArray)
|
||||
return FALSE;
|
||||
pool->aArray = newArray;
|
||||
@ -70,9 +125,14 @@ static BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
|
||||
{
|
||||
if (pool->uSize + count > pool->uCapacity)
|
||||
{
|
||||
int newUCapacity = pool->uCapacity * 2;
|
||||
wBufferPoolItem* newUArray =
|
||||
(wBufferPoolItem*)realloc(pool->uArray, sizeof(wBufferPoolItem) * newUCapacity);
|
||||
SSIZE_T newUCapacity = pool->uCapacity * 2;
|
||||
wBufferPoolItem* newUArray;
|
||||
if (pool->alignment > 0)
|
||||
newUArray = (wBufferPoolItem*)_aligned_realloc(
|
||||
pool->uArray, sizeof(wBufferPoolItem) * newUCapacity, pool->alignment);
|
||||
else
|
||||
newUArray =
|
||||
(wBufferPoolItem*)realloc(pool->uArray, sizeof(wBufferPoolItem) * newUCapacity);
|
||||
if (!newUArray)
|
||||
return FALSE;
|
||||
pool->uCapacity = newUCapacity;
|
||||
@ -96,12 +156,11 @@ static BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
|
||||
* Get the buffer pool size
|
||||
*/
|
||||
|
||||
int BufferPool_GetPoolSize(wBufferPool* pool)
|
||||
SSIZE_T BufferPool_GetPoolSize(wBufferPool* pool)
|
||||
{
|
||||
int size;
|
||||
SSIZE_T size;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
BufferPool_Lock(pool);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -114,8 +173,7 @@ int BufferPool_GetPoolSize(wBufferPool* pool)
|
||||
size = pool->uSize;
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
BufferPool_Unlock(pool);
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -124,14 +182,13 @@ int BufferPool_GetPoolSize(wBufferPool* pool)
|
||||
* Get the size of a pooled buffer
|
||||
*/
|
||||
|
||||
int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer)
|
||||
SSIZE_T BufferPool_GetBufferSize(wBufferPool* pool, const void* buffer)
|
||||
{
|
||||
int size = 0;
|
||||
int index = 0;
|
||||
SSIZE_T size = 0;
|
||||
SSIZE_T index = 0;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
BufferPool_Lock(pool);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -154,8 +211,7 @@ int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer)
|
||||
}
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
BufferPool_Unlock(pool);
|
||||
|
||||
return (found) ? size : -1;
|
||||
}
|
||||
@ -164,17 +220,16 @@ int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer)
|
||||
* Gets a buffer of at least the specified size from the pool.
|
||||
*/
|
||||
|
||||
void* BufferPool_Take(wBufferPool* pool, int size)
|
||||
void* BufferPool_Take(wBufferPool* pool, SSIZE_T size)
|
||||
{
|
||||
int index;
|
||||
int maxSize;
|
||||
int maxIndex;
|
||||
int foundIndex;
|
||||
SSIZE_T index;
|
||||
SSIZE_T maxSize;
|
||||
SSIZE_T maxIndex;
|
||||
SSIZE_T foundIndex;
|
||||
BOOL found = FALSE;
|
||||
void* buffer = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
BufferPool_Lock(pool);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -283,8 +338,7 @@ void* BufferPool_Take(wBufferPool* pool, int size)
|
||||
(pool->uSize)++;
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
BufferPool_Unlock(pool);
|
||||
|
||||
return buffer;
|
||||
|
||||
@ -294,8 +348,7 @@ out_error:
|
||||
else
|
||||
free(buffer);
|
||||
out_error_no_free:
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
BufferPool_Unlock(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -305,12 +358,12 @@ out_error_no_free:
|
||||
|
||||
BOOL BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
int size = 0;
|
||||
int index = 0;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
BufferPool_Lock(pool);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -369,14 +422,10 @@ BOOL BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
}
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return TRUE;
|
||||
|
||||
rc = TRUE;
|
||||
out_error:
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return FALSE;
|
||||
BufferPool_Unlock(pool);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,8 +434,7 @@ out_error:
|
||||
|
||||
void BufferPool_Clear(wBufferPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
BufferPool_Lock(pool);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -427,15 +475,14 @@ void BufferPool_Clear(wBufferPool* pool)
|
||||
}
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
BufferPool_Unlock(pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
|
||||
wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
|
||||
wBufferPool* BufferPool_New(BOOL synchronized, SSIZE_T fixedSize, DWORD alignment)
|
||||
{
|
||||
wBufferPool* pool = NULL;
|
||||
|
||||
@ -488,9 +535,7 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
|
||||
return pool;
|
||||
|
||||
out_error:
|
||||
if (pool->synchronized)
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
free(pool);
|
||||
BufferPool_Free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,20 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
struct _wMessageQueue
|
||||
{
|
||||
size_t head;
|
||||
size_t tail;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
BOOL closed;
|
||||
wMessage* array;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Message Queue inspired from Windows:
|
||||
* http://msdn.microsoft.com/en-us/library/ms632590/
|
||||
@ -35,6 +49,13 @@
|
||||
* Properties
|
||||
*/
|
||||
|
||||
wObject* MessageQueue_Object(wMessageQueue* queue)
|
||||
{
|
||||
if (!queue)
|
||||
return NULL;
|
||||
return &queue->object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an event which is set when the queue is non-empty
|
||||
*/
|
||||
@ -48,7 +69,7 @@ HANDLE MessageQueue_Event(wMessageQueue* queue)
|
||||
* Gets the queue size
|
||||
*/
|
||||
|
||||
int MessageQueue_Size(wMessageQueue* queue)
|
||||
size_t MessageQueue_Size(wMessageQueue* queue)
|
||||
{
|
||||
return queue->size;
|
||||
}
|
||||
@ -67,29 +88,23 @@ BOOL MessageQueue_Wait(wMessageQueue* queue)
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
static BOOL MessageQueue_EnsureCapacity(wMessageQueue* queue, size_t count)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
if (!queue || !message)
|
||||
if (!queue)
|
||||
return FALSE;
|
||||
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->closed)
|
||||
goto out;
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
if (queue->size + count >= queue->capacity)
|
||||
{
|
||||
int old_capacity;
|
||||
int new_capacity;
|
||||
wMessage* new_arr;
|
||||
size_t old_capacity = queue->capacity;
|
||||
size_t new_capacity = queue->capacity * 2;
|
||||
|
||||
old_capacity = queue->capacity;
|
||||
new_capacity = queue->capacity * 2;
|
||||
if (new_capacity < queue->size + count)
|
||||
new_capacity = queue->size + count;
|
||||
|
||||
new_arr = (wMessage*)realloc(queue->array, sizeof(wMessage) * new_capacity);
|
||||
if (!new_arr)
|
||||
goto out;
|
||||
return FALSE;
|
||||
queue->array = new_arr;
|
||||
queue->capacity = new_capacity;
|
||||
ZeroMemory(&(queue->array[old_capacity]), (new_capacity - old_capacity) * sizeof(wMessage));
|
||||
@ -102,10 +117,27 @@ BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
}
|
||||
}
|
||||
|
||||
CopyMemory(&(queue->array[queue->tail]), message, sizeof(wMessage));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
message = &(queue->array[queue->tail]);
|
||||
message->time = GetTickCount64();
|
||||
BOOL MessageQueue_Dispatch(wMessageQueue* queue, const wMessage* message)
|
||||
{
|
||||
wMessage* dst;
|
||||
BOOL ret = FALSE;
|
||||
if (!queue || !message)
|
||||
return FALSE;
|
||||
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->closed)
|
||||
goto out;
|
||||
|
||||
if (!MessageQueue_EnsureCapacity(queue, 1))
|
||||
goto out;
|
||||
|
||||
dst = &(queue->array[queue->tail]);
|
||||
*dst = *message;
|
||||
dst->time = GetTickCount64();
|
||||
|
||||
queue->tail = (queue->tail + 1) % queue->capacity;
|
||||
queue->size++;
|
||||
@ -206,29 +238,23 @@ wMessageQueue* MessageQueue_New(const wObject* callback)
|
||||
if (!queue)
|
||||
return NULL;
|
||||
|
||||
queue->capacity = 32;
|
||||
queue->array = (wMessage*)calloc(queue->capacity, sizeof(wMessage));
|
||||
if (!queue->array)
|
||||
goto error_array;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000))
|
||||
goto error_spinlock;
|
||||
goto fail;
|
||||
|
||||
if (!MessageQueue_EnsureCapacity(queue, 32))
|
||||
goto fail;
|
||||
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!queue->event)
|
||||
goto error_event;
|
||||
goto fail;
|
||||
|
||||
if (callback)
|
||||
queue->object = *callback;
|
||||
|
||||
return queue;
|
||||
|
||||
error_event:
|
||||
DeleteCriticalSection(&queue->lock);
|
||||
error_spinlock:
|
||||
free(queue->array);
|
||||
error_array:
|
||||
free(queue);
|
||||
fail:
|
||||
MessageQueue_Free(queue);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -250,6 +276,9 @@ int MessageQueue_Clear(wMessageQueue* queue)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (!queue || !queue->event)
|
||||
return -1;
|
||||
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
while (queue->size > 0)
|
||||
|
@ -25,6 +25,16 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
struct _wObjectPool
|
||||
{
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
wObject object;
|
||||
BOOL synchronized;
|
||||
};
|
||||
|
||||
/**
|
||||
* C Object Pool similar to C# BufferManager Class:
|
||||
* http://msdn.microsoft.com/en-us/library/ms405814.aspx
|
||||
@ -34,6 +44,18 @@
|
||||
* Methods
|
||||
*/
|
||||
|
||||
static void ObjectPool_Lock(wObjectPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
static void ObjectPool_Unlock(wObjectPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an object from the pool.
|
||||
*/
|
||||
@ -42,8 +64,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
{
|
||||
void* obj = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
ObjectPool_Lock(pool);
|
||||
|
||||
if (pool->size > 0)
|
||||
obj = pool->array[--(pool->size)];
|
||||
@ -57,8 +78,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
if (pool->object.fnObjectInit)
|
||||
pool->object.fnObjectInit(obj);
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
ObjectPool_Unlock(pool);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -69,8 +89,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
|
||||
void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
ObjectPool_Lock(pool);
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
@ -92,8 +111,14 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
pool->object.fnObjectUninit(obj);
|
||||
|
||||
out:
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
ObjectPool_Unlock(pool);
|
||||
}
|
||||
|
||||
wObject* ObjectPool_Object(wObjectPool* pool)
|
||||
{
|
||||
if (!pool)
|
||||
return NULL;
|
||||
return &pool->object;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,8 +127,7 @@ out:
|
||||
|
||||
void ObjectPool_Clear(wObjectPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
EnterCriticalSection(&pool->lock);
|
||||
ObjectPool_Lock(pool);
|
||||
|
||||
while (pool->size > 0)
|
||||
{
|
||||
@ -113,8 +137,7 @@ void ObjectPool_Clear(wObjectPool* pool)
|
||||
pool->object.fnObjectFree(pool->array[pool->size]);
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
ObjectPool_Unlock(pool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,11 +30,21 @@
|
||||
* http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
|
||||
*/
|
||||
|
||||
struct _wPubSub
|
||||
{
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
|
||||
size_t size;
|
||||
size_t count;
|
||||
wEventType* events;
|
||||
};
|
||||
|
||||
/**
|
||||
* Properties
|
||||
*/
|
||||
|
||||
wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count)
|
||||
wEventType* PubSub_GetEventTypes(wPubSub* pubSub, size_t* count)
|
||||
{
|
||||
if (count)
|
||||
*count = pubSub->count;
|
||||
@ -48,17 +58,19 @@ wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count)
|
||||
|
||||
void PubSub_Lock(wPubSub* pubSub)
|
||||
{
|
||||
EnterCriticalSection(&pubSub->lock);
|
||||
if (pubSub->synchronized)
|
||||
EnterCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
void PubSub_Unlock(wPubSub* pubSub)
|
||||
{
|
||||
LeaveCriticalSection(&pubSub->lock);
|
||||
if (pubSub->synchronized)
|
||||
LeaveCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
wEventType* event = NULL;
|
||||
|
||||
for (index = 0; index < pubSub->count; index++)
|
||||
@ -73,7 +85,7 @@ wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
|
||||
return event;
|
||||
}
|
||||
|
||||
void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count)
|
||||
void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, size_t count)
|
||||
{
|
||||
if (pubSub->synchronized)
|
||||
PubSub_Lock(pubSub);
|
||||
@ -126,7 +138,7 @@ int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler Event
|
||||
|
||||
int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
wEventType* event;
|
||||
int status = -1;
|
||||
|
||||
@ -195,9 +207,7 @@ int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEvent
|
||||
|
||||
wPubSub* PubSub_New(BOOL synchronized)
|
||||
{
|
||||
wPubSub* pubSub = NULL;
|
||||
|
||||
pubSub = (wPubSub*)malloc(sizeof(wPubSub));
|
||||
wPubSub* pubSub = (wPubSub*)calloc(1, sizeof(wPubSub));
|
||||
|
||||
if (!pubSub)
|
||||
return NULL;
|
||||
@ -205,24 +215,19 @@ wPubSub* PubSub_New(BOOL synchronized)
|
||||
pubSub->synchronized = synchronized;
|
||||
|
||||
if (pubSub->synchronized && !InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000))
|
||||
{
|
||||
free(pubSub);
|
||||
return NULL;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
pubSub->count = 0;
|
||||
pubSub->size = 64;
|
||||
|
||||
pubSub->events = (wEventType*)calloc(pubSub->size, sizeof(wEventType));
|
||||
if (!pubSub->events)
|
||||
{
|
||||
if (pubSub->synchronized)
|
||||
DeleteCriticalSection(&pubSub->lock);
|
||||
free(pubSub);
|
||||
return NULL;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
return pubSub;
|
||||
fail:
|
||||
PubSub_Free(pubSub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PubSub_Free(wPubSub* pubSub)
|
||||
|
@ -25,6 +25,22 @@
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
struct _wQueue
|
||||
{
|
||||
size_t capacity;
|
||||
size_t growthFactor;
|
||||
BOOL synchronized;
|
||||
|
||||
size_t head;
|
||||
size_t tail;
|
||||
size_t size;
|
||||
void** array;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
|
||||
/**
|
||||
* C equivalent of the C# Queue Class:
|
||||
* http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx
|
||||
@ -40,15 +56,13 @@
|
||||
|
||||
int Queue_Count(wQueue* queue)
|
||||
{
|
||||
int ret;
|
||||
size_t ret;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
Queue_Lock(queue);
|
||||
|
||||
ret = queue->size;
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -59,7 +73,8 @@ int Queue_Count(wQueue* queue)
|
||||
|
||||
void Queue_Lock(wQueue* queue)
|
||||
{
|
||||
EnterCriticalSection(&queue->lock);
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +83,8 @@ void Queue_Lock(wQueue* queue)
|
||||
|
||||
void Queue_Unlock(wQueue* queue)
|
||||
{
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,6 +96,13 @@ HANDLE Queue_Event(wQueue* queue)
|
||||
return queue->event;
|
||||
}
|
||||
|
||||
wObject* Queue_Object(wQueue* queue)
|
||||
{
|
||||
if (!queue)
|
||||
return NULL;
|
||||
return &queue->object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods
|
||||
*/
|
||||
@ -90,10 +113,9 @@ HANDLE Queue_Event(wQueue* queue)
|
||||
|
||||
void Queue_Clear(wQueue* queue)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
Queue_Lock(queue);
|
||||
|
||||
for (index = queue->head; index != queue->tail; index = (index + 1) % queue->capacity)
|
||||
{
|
||||
@ -106,21 +128,19 @@ void Queue_Clear(wQueue* queue)
|
||||
queue->size = 0;
|
||||
queue->head = queue->tail = 0;
|
||||
ResetEvent(queue->event);
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an element is in the Queue.
|
||||
*/
|
||||
|
||||
BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
BOOL Queue_Contains(wQueue* queue, const void* obj)
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
Queue_Lock(queue);
|
||||
|
||||
for (index = 0; index < queue->tail; index++)
|
||||
{
|
||||
@ -131,37 +151,27 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
}
|
||||
}
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the end of the Queue.
|
||||
*/
|
||||
|
||||
BOOL Queue_Enqueue(wQueue* queue, void* obj)
|
||||
static BOOL Queue_EnsureCapacity(wQueue* queue, size_t count)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
if (!queue)
|
||||
return FALSE;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
if (queue->size + count >= queue->capacity)
|
||||
{
|
||||
int old_capacity;
|
||||
int new_capacity;
|
||||
const size_t old_capacity = queue->capacity;
|
||||
size_t new_capacity = queue->capacity * queue->growthFactor;
|
||||
void** newArray;
|
||||
old_capacity = queue->capacity;
|
||||
new_capacity = queue->capacity * queue->growthFactor;
|
||||
if (new_capacity < queue->size + count)
|
||||
new_capacity = queue->size + count;
|
||||
newArray = (void**)realloc(queue->array, sizeof(void*) * new_capacity);
|
||||
|
||||
if (!newArray)
|
||||
{
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
queue->capacity = new_capacity;
|
||||
queue->array = newArray;
|
||||
@ -174,6 +184,21 @@ BOOL Queue_Enqueue(wQueue* queue, void* obj)
|
||||
queue->tail += old_capacity;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the end of the Queue.
|
||||
*/
|
||||
|
||||
BOOL Queue_Enqueue(wQueue* queue, void* obj)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
Queue_Lock(queue);
|
||||
|
||||
if (!Queue_EnsureCapacity(queue, 1))
|
||||
goto out;
|
||||
|
||||
queue->array[queue->tail] = obj;
|
||||
queue->tail = (queue->tail + 1) % queue->capacity;
|
||||
@ -181,8 +206,7 @@ BOOL Queue_Enqueue(wQueue* queue, void* obj)
|
||||
SetEvent(queue->event);
|
||||
out:
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -195,8 +219,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
{
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
Queue_Lock(queue);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -209,8 +232,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
if (queue->size < 1)
|
||||
ResetEvent(queue->event);
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -223,14 +245,12 @@ void* Queue_Peek(wQueue* queue)
|
||||
{
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
EnterCriticalSection(&queue->lock);
|
||||
Queue_Lock(queue);
|
||||
|
||||
if (queue->size > 0)
|
||||
obj = queue->array[queue->head];
|
||||
|
||||
if (queue->synchronized)
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
Queue_Unlock(queue);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -246,43 +266,40 @@ static BOOL default_queue_equals(const void* obj1, const void* obj2)
|
||||
|
||||
wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
||||
{
|
||||
wObject* obj;
|
||||
wQueue* queue = NULL;
|
||||
queue = (wQueue*)calloc(1, sizeof(wQueue));
|
||||
|
||||
if (!queue)
|
||||
return NULL;
|
||||
|
||||
queue->capacity = 32;
|
||||
queue->growthFactor = 2;
|
||||
queue->synchronized = synchronized;
|
||||
|
||||
if (capacity > 0)
|
||||
queue->capacity = capacity;
|
||||
|
||||
queue->growthFactor = 2;
|
||||
if (growthFactor > 0)
|
||||
queue->growthFactor = growthFactor;
|
||||
|
||||
queue->array = (void**)calloc(queue->capacity, sizeof(void*));
|
||||
|
||||
if (!queue->array)
|
||||
goto out_free;
|
||||
if (capacity <= 0)
|
||||
capacity = 32;
|
||||
if (!Queue_EnsureCapacity(queue, capacity))
|
||||
goto fail;
|
||||
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (!queue->event)
|
||||
goto out_free_array;
|
||||
goto fail;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000))
|
||||
goto out_free_event;
|
||||
goto fail;
|
||||
|
||||
obj = Queue_Object(queue);
|
||||
if (!obj)
|
||||
goto fail;
|
||||
obj->fnObjectEquals = default_queue_equals;
|
||||
|
||||
queue->object.fnObjectEquals = default_queue_equals;
|
||||
return queue;
|
||||
out_free_event:
|
||||
CloseHandle(queue->event);
|
||||
out_free_array:
|
||||
free(queue->array);
|
||||
out_free:
|
||||
free(queue);
|
||||
fail:
|
||||
Queue_Free(queue);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user