aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/msgpack_rpc
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-04-28 20:37:52 +0200
committerGitHub <noreply@github.com>2017-04-28 20:37:52 +0200
commit129f107c0c26fbf371bcf165ec20eb13356bfb8e (patch)
tree864bf25c65c6cfcd4e17c0ebd04afdad1342c268 /src/nvim/msgpack_rpc
parent7044aa6e8256844bc1bd23eb61d4a41ca6d418d0 (diff)
parent8f59d1483934f91011b755406251136c406e77f6 (diff)
downloadrneovim-129f107c0c26fbf371bcf165ec20eb13356bfb8e.tar.gz
rneovim-129f107c0c26fbf371bcf165ec20eb13356bfb8e.tar.bz2
rneovim-129f107c0c26fbf371bcf165ec20eb13356bfb8e.zip
Merge #6247 'api: nvim_get_mode()'
Diffstat (limited to 'src/nvim/msgpack_rpc')
-rw-r--r--src/nvim/msgpack_rpc/channel.c25
-rw-r--r--src/nvim/msgpack_rpc/channel.h5
-rw-r--r--src/nvim/msgpack_rpc/helpers.c2
3 files changed, 24 insertions, 8 deletions
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 59594357de..911f2a6fa4 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -29,6 +29,7 @@
#include "nvim/log.h"
#include "nvim/misc1.h"
#include "nvim/lib/kvec.h"
+#include "nvim/os/input.h"
#define CHANNEL_BUFFER_SIZE 0xffff
@@ -89,6 +90,7 @@ static msgpack_sbuffer out_buffer;
/// Initializes the module
void channel_init(void)
{
+ ch_before_blocking_events = multiqueue_new_child(main_loop.events);
channels = pmap_new(uint64_t)();
event_strings = pmap_new(cstr_t)();
msgpack_sbuffer_init(&out_buffer);
@@ -433,16 +435,25 @@ static void handle_request(Channel *channel, msgpack_object *request)
handler.async = true;
}
- RequestEvent *event_data = xmalloc(sizeof(RequestEvent));
- event_data->channel = channel;
- event_data->handler = handler;
- event_data->args = args;
- event_data->request_id = request_id;
+ RequestEvent *evdata = xmalloc(sizeof(RequestEvent));
+ evdata->channel = channel;
+ evdata->handler = handler;
+ evdata->args = args;
+ evdata->request_id = request_id;
incref(channel);
if (handler.async) {
- on_request_event((void **)&event_data);
+ bool is_get_mode = sizeof("nvim_get_mode") - 1 == method->via.bin.size
+ && !strncmp("nvim_get_mode", method->via.bin.ptr, method->via.bin.size);
+
+ if (is_get_mode && !input_blocking()) {
+ // Defer the event to a special queue used by os/input.c. #6247
+ multiqueue_put(ch_before_blocking_events, on_request_event, 1, evdata);
+ } else {
+ // Invoke immediately.
+ on_request_event((void **)&evdata);
+ }
} else {
- multiqueue_put(channel->events, on_request_event, 1, event_data);
+ multiqueue_put(channel->events, on_request_event, 1, evdata);
}
}
diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h
index 0d92976d02..f8fe6f129b 100644
--- a/src/nvim/msgpack_rpc/channel.h
+++ b/src/nvim/msgpack_rpc/channel.h
@@ -11,6 +11,11 @@
#define METHOD_MAXLEN 512
+/// HACK: os/input.c drains this queue immediately before blocking for input.
+/// Events on this queue are async-safe, but they need the resolved state
+/// of os_inchar(), so they are processed "just-in-time".
+MultiQueue *ch_before_blocking_events;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/channel.h.generated.h"
#endif
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 0228582d37..91ef5524ea 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -76,7 +76,7 @@ typedef struct {
size_t idx;
} MPToAPIObjectStackItem;
-/// Convert type used by msgpack parser to Neovim own API type
+/// Convert type used by msgpack parser to Nvim API type.
///
/// @param[in] obj Msgpack value to convert.
/// @param[out] arg Location where result of conversion will be saved.