@@ -95,14 +95,19 @@ void async_callback(void *param)
95
95
// Queue this event up for later, if that's how we've been configured.
96
96
if (listener->flags & MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY)
97
97
{
98
+ #if (MESSAGE_BUS_CONCURRENCY_MODE == MESSAGE_BUS_CONCURRENT_LISTENERS)
98
99
listener->queue (listener->evt );
99
100
return ;
101
+ #endif
100
102
}
101
103
}
102
104
103
105
// Determine the calling convention for the callback, and invoke...
104
106
// C++ is really bad at this! Especially as the ARM compiler is yet to support C++ 11 :-/
105
107
108
+ #if (MESSAGE_BUS_CONCURRENCY_MODE == MESSAGE_BUS_CONCURRENT_EVENTS)
109
+ listener->lock .wait ();
110
+ #endif
106
111
// Record that we have a fiber going into this listener...
107
112
listener->flags |= MESSAGE_BUS_LISTENER_BUSY;
108
113
@@ -138,6 +143,10 @@ void async_callback(void *param)
138
143
139
144
// The fiber of exiting... clear our state.
140
145
listener->flags &= ~MESSAGE_BUS_LISTENER_BUSY;
146
+
147
+ #if (MESSAGE_BUS_CONCURRENCY_MODE == MESSAGE_BUS_CONCURRENT_EVENTS)
148
+ listener->lock .notify ();
149
+ #endif
141
150
}
142
151
143
152
/* *
@@ -261,6 +270,13 @@ int MicroBitMessageBus::deleteMarkedListeners()
261
270
return removed;
262
271
}
263
272
273
+ MicroBitEvent last_event;
274
+ void process_sequentially (void *param)
275
+ {
276
+ MicroBitMessageBus *m = (MicroBitMessageBus *)param;
277
+ m->process (last_event);
278
+ }
279
+
264
280
/* *
265
281
* Periodic callback from MicroBit.
266
282
*
@@ -278,7 +294,12 @@ void MicroBitMessageBus::idleTick()
278
294
while (item)
279
295
{
280
296
// send the event to all standard event listeners.
297
+ #if (MESSAGE_BUS_CONCURRENCY_MODE == MESSAGE_BUS_CONCURRENT_EVENTS)
298
+ last_event = item->evt ;
299
+ invoke (process_sequentially,this );
300
+ #else
281
301
this ->process (item->evt );
302
+ #endif
282
303
283
304
// Free the queue item.
284
305
delete item;
@@ -365,10 +386,12 @@ int MicroBitMessageBus::process(MicroBitEvent &evt, bool urgent)
365
386
// Otherwise, we invoke it in a 'fork on block' context, that will automatically create a fiber
366
387
// should the event handler attempt a blocking operation, but doesn't have the overhead
367
388
// of creating a fiber needlessly. (cool huh?)
368
- if (l->flags & MESSAGE_BUS_LISTENER_NONBLOCKING || !fiber_scheduler_running ())
369
- async_callback (l);
370
- else
389
+ #if (MESSAGE_BUS_CONCURRENCY_MODE == MESSAGE_BUS_CONCURRENT_LISTENERS)
390
+ if (!(l->flags & MESSAGE_BUS_LISTENER_NONBLOCKING) && fiber_scheduler_running ())
371
391
invoke (async_callback, l);
392
+ else
393
+ #endif
394
+ async_callback (l);
372
395
}
373
396
else
374
397
{
0 commit comments