25
25
#include "esif_uf_eventmgr.h"
26
26
#include "esif_queue.h"
27
27
#include "esif_uf_sensors.h"
28
+ #include "esif_uf_ccb_timedwait.h"
28
29
29
30
30
31
#define NUM_EVENT_LISTS 64
@@ -56,6 +57,9 @@ typedef struct EsifEventMgr_s {
56
57
esif_ccb_lock_t appUnregisterListLock ;
57
58
Bool delayedAppUnregistrationEnabled ;
58
59
Bool delayAppUnregistration ;
60
+
61
+ /* Used to control destruction of the context for synchronous events */
62
+ esif_ccb_lock_t synchronousEventLock ;
59
63
}EsifEventMgr , * EsifEventMgrPtr ;
60
64
61
65
typedef struct EventMgrEntry_s {
@@ -73,13 +77,20 @@ typedef struct EventMgrEntry_s {
73
77
Bool markedForDelete ; /* Indicates the event is marked for deletion */
74
78
} EventMgrEntry , * EventMgrEntryPtr ;
75
79
80
+
81
+ typedef struct EsifEventMgr_SynchronousEventContext_s {
82
+ Bool useComplete ;
83
+ esif_ccb_event_t completionEvent ;
84
+ } EsifEventMgr_SynchronousEventContext ;
85
+
76
86
typedef struct EsifEventQueueItem_s {
77
87
esif_handle_t participantId ;
78
88
UInt16 domainId ;
79
89
eEsifEventType eventType ;
80
90
EsifData eventData ;
81
91
Bool isLfEvent ;
82
92
Bool isUnfiltered ;
93
+ EsifEventMgr_SynchronousEventContext * syncContextPtr ;
83
94
}EsifEventQueueItem , * EsifEventQueueItemPtr ;
84
95
85
96
@@ -166,12 +177,16 @@ static eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local (
166
177
eEsifEventType eventType ,
167
178
const EsifDataPtr eventDataPtr ,
168
179
Bool isLfEvent ,
169
- Bool isFilteredEvent
180
+ Bool isFilteredEvent ,
181
+ EsifEventMgr_SynchronousEventContext * syncContextPtr
170
182
);
171
183
172
184
static Bool EsifEventMgr_IsEventFiltered (eEsifEventType eventType );
173
185
static Bool EsifEventMgr_IsEventCacheable (eEsifEventType eventType );
174
186
187
+ static void DestroySynchronizationContext (EsifEventMgr_SynchronousEventContext * syncContextPtr );
188
+
189
+
175
190
/*
176
191
* Friend function: Target is determined only once removed from queue and all
177
192
* others before it have been processed
@@ -191,7 +206,69 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent(
191
206
const EsifDataPtr eventDataPtr
192
207
)
193
208
{
194
- return EsifEventMgr_SignalEvent_Local (participantId , domainId , eventType , eventDataPtr , ESIF_FALSE , ESIF_TRUE );
209
+ return EsifEventMgr_SignalEvent_Local (participantId , domainId , eventType , eventDataPtr , ESIF_FALSE , ESIF_TRUE , NULL );
210
+ }
211
+
212
+ /*
213
+ * Used to signal an event that will be processed synchronously for up to the
214
+ * specified wait time
215
+ * NOTE: Maximum allowed wait time is EVENT_MGR_SYNCHRONOUS_EVENT_TIME_MAX
216
+ */
217
+ eEsifError ESIF_CALLCONV EsifEventMgr_SignalSynchronousEvent (
218
+ esif_handle_t participantId ,
219
+ UInt16 domainId ,
220
+ eEsifEventType eventType ,
221
+ const EsifDataPtr eventDataPtr ,
222
+ esif_ccb_time_t msWait
223
+ )
224
+ {
225
+ esif_error_t rc = ESIF_OK ;
226
+ EsifEventMgr_SynchronousEventContext * syncContextPtr = NULL ;
227
+
228
+ syncContextPtr = (EsifEventMgr_SynchronousEventContext * )esif_ccb_malloc (sizeof (* syncContextPtr ));
229
+ if (!syncContextPtr ) {
230
+ rc = ESIF_E_NO_MEMORY ;
231
+ goto exit ;
232
+ }
233
+ esif_ccb_event_init (& syncContextPtr -> completionEvent );
234
+ esif_ccb_event_reset (& syncContextPtr -> completionEvent );
235
+
236
+ rc = EsifEventMgr_SignalEvent_Local (participantId , domainId , eventType , eventDataPtr , ESIF_FALSE , ESIF_TRUE , syncContextPtr );
237
+
238
+ EsifTimedEventWait (& syncContextPtr -> completionEvent , esif_ccb_min (msWait , EVENT_MGR_SYNCHRONOUS_EVENT_TIME_MAX ));
239
+
240
+ DestroySynchronizationContext (syncContextPtr );
241
+ exit :
242
+ return rc ;
243
+ }
244
+
245
+
246
+ static void DestroySynchronizationContext (
247
+ EsifEventMgr_SynchronousEventContext * syncContextPtr
248
+ )
249
+ {
250
+ Bool canDestroyContext = ESIF_FALSE ;
251
+
252
+ if (syncContextPtr ) {
253
+ esif_ccb_write_lock (& g_EsifEventMgr .synchronousEventLock );
254
+
255
+ if (syncContextPtr -> useComplete ) {
256
+ /* If other thread is already done, mark to destroy context by current thread */
257
+ canDestroyContext = ESIF_TRUE ;
258
+ }
259
+ else {
260
+ /* Indicate current thread is done using context so it can be destroyed by other thread */
261
+ syncContextPtr -> useComplete = ESIF_TRUE ;
262
+ }
263
+
264
+ esif_ccb_write_unlock (& g_EsifEventMgr .synchronousEventLock );
265
+
266
+ /* Destroy context outside locks if needed */
267
+ if (canDestroyContext ) {
268
+ esif_ccb_event_uninit (& syncContextPtr -> completionEvent );
269
+ esif_ccb_free (syncContextPtr );
270
+ }
271
+ }
195
272
}
196
273
197
274
@@ -206,7 +283,7 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalLfEvent(
206
283
const EsifDataPtr eventDataPtr
207
284
)
208
285
{
209
- return EsifEventMgr_SignalEvent_Local (targetId , domainId , eventType , eventDataPtr , ESIF_TRUE , ESIF_TRUE );
286
+ return EsifEventMgr_SignalEvent_Local (targetId , domainId , eventType , eventDataPtr , ESIF_TRUE , ESIF_TRUE , NULL );
210
287
}
211
288
212
289
@@ -217,17 +294,18 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalUnfilteredEvent(
217
294
const EsifDataPtr eventDataPtr
218
295
)
219
296
{
220
- return EsifEventMgr_SignalEvent_Local (participantId , domainId , eventType , eventDataPtr , ESIF_FALSE , ESIF_FALSE );
297
+ return EsifEventMgr_SignalEvent_Local (participantId , domainId , eventType , eventDataPtr , ESIF_FALSE , ESIF_FALSE , NULL );
221
298
}
222
299
223
300
224
- eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local (
301
+ static eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local (
225
302
esif_handle_t participantId ,
226
303
UInt16 domainId ,
227
304
eEsifEventType eventType ,
228
305
const EsifDataPtr eventDataPtr ,
229
306
Bool isLfEvent ,
230
- Bool isFilteredEvent
307
+ Bool isFilteredEvent ,
308
+ EsifEventMgr_SynchronousEventContext * syncContextPtr
231
309
)
232
310
{
233
311
eEsifError rc = ESIF_OK ;
@@ -250,7 +328,10 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local(
250
328
rc = ESIF_E_NO_MEMORY ;
251
329
goto exit ;
252
330
}
253
-
331
+ /*
332
+ * Make a copy of the data as the thread exposing it will continue and may
333
+ * destroy it
334
+ */
254
335
if ((eventDataPtr != NULL ) &&
255
336
(eventDataPtr -> buf_ptr != NULL ) &&
256
337
(eventDataPtr -> buf_len > 0 ) &&
@@ -275,6 +356,7 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local(
275
356
queueEventPtr -> domainId = domainId ;
276
357
queueEventPtr -> eventType = eventType ;
277
358
queueEventPtr -> isLfEvent = isLfEvent ;
359
+ queueEventPtr -> syncContextPtr = syncContextPtr ;
278
360
279
361
ESIF_TRACE_INFO ("Queuing %s event for Part. %u Dom. 0x%04X\n" ,
280
362
esif_event_type_str (eventType ),
@@ -290,7 +372,11 @@ eEsifError ESIF_CALLCONV EsifEventMgr_SignalEvent_Local(
290
372
if (rc != ESIF_OK ) {
291
373
esif_ccb_free (queueEventPtr );
292
374
esif_ccb_free (queueDataPtr );
293
-
375
+ if (syncContextPtr ) {
376
+ /* Release synchronous waiter and destroy context if needed */
377
+ esif_ccb_event_set (& syncContextPtr -> completionEvent );
378
+ DestroySynchronizationContext (syncContextPtr );
379
+ }
294
380
}
295
381
return rc ;
296
382
}
@@ -334,6 +420,12 @@ static void *ESIF_CALLCONV EsifEventMgr_EventQueueThread(void *ctxPtr)
334
420
queueEventPtr -> eventType ,
335
421
& queueEventPtr -> eventData );
336
422
}
423
+
424
+ /* Release any synchronous event waiters */
425
+ if (queueEventPtr -> syncContextPtr ) {
426
+ esif_ccb_event_set (& queueEventPtr -> syncContextPtr -> completionEvent );
427
+ DestroySynchronizationContext (queueEventPtr -> syncContextPtr );
428
+ }
337
429
esif_ccb_free (queueEventPtr -> eventData .buf_ptr );
338
430
esif_ccb_free (queueEventPtr );
339
431
}
@@ -1243,6 +1335,8 @@ eEsifError EsifEventMgr_Init(void)
1243
1335
1244
1336
esif_ccb_lock_init (& g_EsifEventMgr .listLock );
1245
1337
esif_ccb_lock_init (& g_EsifEventMgr .appUnregisterListLock );
1338
+ esif_ccb_lock_init (& g_EsifEventMgr .synchronousEventLock );
1339
+
1246
1340
1247
1341
for (i = 0 ; i < NUM_EVENT_LISTS ; i ++ ) {
1248
1342
g_EsifEventMgr .observerLists [i ] = esif_link_list_create ();
@@ -1343,6 +1437,7 @@ void EsifEventMgr_Exit(void)
1343
1437
g_EsifEventMgr .garbageList = NULL ;
1344
1438
esif_ccb_write_unlock (& g_EsifEventMgr .listLock );
1345
1439
1440
+ esif_ccb_lock_uninit (& g_EsifEventMgr .synchronousEventLock );
1346
1441
esif_ccb_lock_uninit (& g_EsifEventMgr .listLock );
1347
1442
esif_ccb_lock_uninit (& g_EsifEventMgr .appUnregisterListLock );
1348
1443
0 commit comments