diff options
Diffstat (limited to 'src/nvim/event/multiqueue.c')
-rw-r--r-- | src/nvim/event/multiqueue.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index ef9f3f1870..a1b75f66a5 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -78,6 +78,13 @@ struct multiqueue { size_t size; }; +typedef struct { + Event event; + bool fired; + int refcount; +} SplitEvent; + + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.c.generated.h" #endif @@ -245,3 +252,33 @@ static MultiQueueItem *multiqueue_node_data(QUEUE *q) { return QUEUE_DATA(q, MultiQueueItem, node); } + +/// Allow an event to be processed by multiple child queues to the main queue +/// +/// The handler will be fired once by the _first_ queue that processes the +/// event. Later processing will do nothing (just memory cleanup). +/// +/// @param ev the event +/// @param num number of queues that the split event will be put on +/// @return an Event that is safe to put onto `num` queues +Event event_split(Event ev, int num) +{ + SplitEvent *data = xmalloc(sizeof(*data)); + data->event = ev; + data->fired = false; + data->refcount = num; + return event_create(split_event, 1, data); +} +static void split_event(void ** argv) +{ + SplitEvent *data = argv[0]; + if (!data->fired) { + data->fired = true; + if (data->event.handler) { + data->event.handler(data->event.argv); + } + } + if ((--data->refcount) == 0) { + xfree(data); + } +} |