aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event/multiqueue.c
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-09-07 13:00:51 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-09-08 15:24:14 +0200
commit19993bca4afaade5d0fbaf132ff66064370bacb0 (patch)
tree6d81b8d88d70e83cd02b1ab2079d6415f973ae2a /src/nvim/event/multiqueue.c
parentbf9ff5148a57c64c26dd3786a4028418a6047e4a (diff)
downloadrneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.tar.gz
rneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.tar.bz2
rneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.zip
rpc: allow handling of nvim_ui_try_resize at the pager
This makes external UI behave consistenly with TUI w.r.t resizes. Which will be needed anyway as TUI will use the external UI protocol soon.
Diffstat (limited to 'src/nvim/event/multiqueue.c')
-rw-r--r--src/nvim/event/multiqueue.c37
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);
+ }
+}