Cleaned up collections:

ArrayList, MessageQueue, Queue, PubSub, BipBuffer
ObjectPool and BufferPool
This commit is contained in:
akallabeth 2020-05-12 17:16:14 +02:00 committed by akallabeth
parent 96bb569674
commit 6e3c00725a
24 changed files with 761 additions and 597 deletions

View File

@ -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);

View File

@ -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)))

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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))

View File

@ -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++)
{

View File

@ -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;
}

View File

@ -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
{

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}
/**

View File

@ -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)

View File

@ -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;
}