diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index f7de630d6..9dd59a2f5 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -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); diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 29de65553..93a4579f4 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -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))) diff --git a/channels/rdpsnd/client/opensles/opensl_io.c b/channels/rdpsnd/client/opensles/opensl_io.c index 61afc108f..0dad40b9b 100644 --- a/channels/rdpsnd/client/opensles/opensl_io.c +++ b/channels/rdpsnd/client/opensles/opensl_io.c @@ -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; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index a85cce6da..fd88355f6 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -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) { diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index b77a3c642..2bf8f76bd 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -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; diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index ec7b0b322..0f7543775 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -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; diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 3f7d8727c..4f2f0a2eb 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -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"); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 794acea0c..9e2203e80 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -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"); diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index b7db992ee..652f02fe8 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -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)); diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 52d1625f7..1ec53a3d0 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -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; diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 4b823887c..f37a22c65 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -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); diff --git a/server/proxy/pf_modules.c b/server/proxy/pf_modules.c index 0d0d8ff48..66dba97d7 100644 --- a/server/proxy/pf_modules.c +++ b/server/proxy/pf_modules.c @@ -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; } diff --git a/server/proxy/pf_server.c b/server/proxy/pf_server.c index 06fe29a76..766951467 100644 --- a/server/proxy/pf_server.c +++ b/server/proxy/pf_server.c @@ -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) diff --git a/server/shadow/shadow_subsystem.c b/server/shadow/shadow_subsystem.c index aee87e1dc..f587d1103 100644 --- a/server/shadow/shadow_subsystem.c +++ b/server/shadow/shadow_subsystem.c @@ -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; diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index b11762bcb..483e43427 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/winpr/libwinpr/clipboard/posix.c b/winpr/libwinpr/clipboard/posix.c index 36e685d1c..05052d90d 100644 --- a/winpr/libwinpr/clipboard/posix.c +++ b/winpr/libwinpr/clipboard/posix.c @@ -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)) diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c index 54a0585da..9b2e7dc32 100644 --- a/winpr/libwinpr/pool/pool.c +++ b/winpr/libwinpr/pool/pool.c @@ -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++) { diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index f8fc3df06..94ab8bd95 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -25,6 +25,19 @@ #include +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; } diff --git a/winpr/libwinpr/utils/collections/BipBuffer.c b/winpr/libwinpr/utils/collections/BipBuffer.c index 3efe3b7cd..3fd5e9866 100644 --- a/winpr/libwinpr/utils/collections/BipBuffer.c +++ b/winpr/libwinpr/utils/collections/BipBuffer.c @@ -27,23 +27,46 @@ #include +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 { diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index 5120a9106..3e3f5be57 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -25,6 +25,57 @@ #include +/* 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; } diff --git a/winpr/libwinpr/utils/collections/MessageQueue.c b/winpr/libwinpr/utils/collections/MessageQueue.c index 4e22806b5..fd0938ece 100644 --- a/winpr/libwinpr/utils/collections/MessageQueue.c +++ b/winpr/libwinpr/utils/collections/MessageQueue.c @@ -26,6 +26,20 @@ #include +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) diff --git a/winpr/libwinpr/utils/collections/ObjectPool.c b/winpr/libwinpr/utils/collections/ObjectPool.c index 5f80a31bb..5c22cea30 100644 --- a/winpr/libwinpr/utils/collections/ObjectPool.c +++ b/winpr/libwinpr/utils/collections/ObjectPool.c @@ -25,6 +25,16 @@ #include +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); } /** diff --git a/winpr/libwinpr/utils/collections/PubSub.c b/winpr/libwinpr/utils/collections/PubSub.c index 466dde689..841a80010 100644 --- a/winpr/libwinpr/utils/collections/PubSub.c +++ b/winpr/libwinpr/utils/collections/PubSub.c @@ -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) diff --git a/winpr/libwinpr/utils/collections/Queue.c b/winpr/libwinpr/utils/collections/Queue.c index 491851686..d0f00f152 100644 --- a/winpr/libwinpr/utils/collections/Queue.c +++ b/winpr/libwinpr/utils/collections/Queue.c @@ -25,6 +25,22 @@ #include +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; }