20#include <winpr/config.h>
24#include <winpr/collections.h>
45wEventType* PubSub_GetEventTypes(wPubSub* pubSub,
size_t* count)
49 *count = pubSub->count;
51 return pubSub->events;
58void PubSub_Lock(wPubSub* pubSub)
61 if (pubSub->synchronized)
62 EnterCriticalSection(&pubSub->lock);
65void PubSub_Unlock(wPubSub* pubSub)
68 if (pubSub->synchronized)
69 LeaveCriticalSection(&pubSub->lock);
72wEventType* PubSub_FindEventType(wPubSub* pubSub,
const char* EventName)
77 WINPR_ASSERT(EventName);
78 for (
size_t index = 0; index < pubSub->count; index++)
80 if (strcmp(pubSub->events[index].EventName, EventName) == 0)
82 event = &(pubSub->events[index]);
90void PubSub_AddEventTypes(wPubSub* pubSub,
wEventType* events,
size_t count)
93 WINPR_ASSERT(events || (count == 0));
94 if (pubSub->synchronized)
97 const size_t required = pubSub->count + count;
98 WINPR_ASSERT((required >= pubSub->count) && (required >= count));
100 if (required >= pubSub->size)
102 size_t new_size = pubSub->size;
105 WINPR_ASSERT(new_size <= SIZE_MAX - 128ull);
107 }
while (new_size <= required);
112 pubSub->size = new_size;
113 pubSub->events = new_event;
116 CopyMemory(&pubSub->events[pubSub->count], events, count *
sizeof(
wEventType));
117 pubSub->count += count;
120 if (pubSub->synchronized)
121 PubSub_Unlock(pubSub);
124int PubSub_Subscribe(wPubSub* pubSub,
const char* EventName, ...)
128 WINPR_ASSERT(pubSub);
131 va_start(ap, EventName);
132 pEventHandler EventHandler = va_arg(ap, pEventHandler);
134 if (pubSub->synchronized)
137 event = PubSub_FindEventType(pubSub, EventName);
143 if (event->EventHandlerCount < MAX_EVENT_HANDLERS)
144 event->EventHandlers[
event->EventHandlerCount++] = EventHandler;
149 if (pubSub->synchronized)
150 PubSub_Unlock(pubSub);
156int PubSub_Unsubscribe(wPubSub* pubSub,
const char* EventName, ...)
160 WINPR_ASSERT(pubSub);
161 WINPR_ASSERT(EventName);
164 va_start(ap, EventName);
165 pEventHandler EventHandler = va_arg(ap, pEventHandler);
167 if (pubSub->synchronized)
170 event = PubSub_FindEventType(pubSub, EventName);
176 for (
size_t index = 0; index <
event->EventHandlerCount; index++)
178 if (event->EventHandlers[index] == EventHandler)
180 event->EventHandlers[index] = NULL;
181 event->EventHandlerCount--;
182 MoveMemory((
void*)&event->EventHandlers[index],
183 (
void*)&event->EventHandlers[index + 1],
184 (MAX_EVENT_HANDLERS - index - 1) *
sizeof(pEventHandler));
190 if (pubSub->synchronized)
191 PubSub_Unlock(pubSub);
197int PubSub_OnEvent(wPubSub* pubSub,
const char* EventName,
void* context,
const wEventArgs* e)
206 if (pubSub->synchronized)
209 event = PubSub_FindEventType(pubSub, EventName);
211 if (pubSub->synchronized)
212 PubSub_Unlock(pubSub);
218 for (
size_t index = 0; index <
event->EventHandlerCount; index++)
220 if (event->EventHandlers[index])
222 event->EventHandlers[index](context, e);
235wPubSub* PubSub_New(BOOL
synchronized)
237 wPubSub* pubSub = (wPubSub*)calloc(1,
sizeof(wPubSub));
242 pubSub->synchronized =
synchronized;
244 if (pubSub->synchronized && !InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000))
256 WINPR_PRAGMA_DIAG_PUSH
257 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
259 WINPR_PRAGMA_DIAG_POP
263void PubSub_Free(wPubSub* pubSub)
267 if (pubSub->synchronized)
268 DeleteCriticalSection(&pubSub->lock);
270 free(pubSub->events);