aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2017-10-29 03:06:53 +0100
committerJustin M. Keyes <justinkz@gmail.com>2017-10-29 03:06:53 +0100
commit2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17 (patch)
treee3e2555c63c21ab05ba9820c38465e42f7abb465 /src
parent3a938fff0954513f34704485e53dcb9a0cc7c59d (diff)
downloadrneovim-2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17.tar.gz
rneovim-2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17.tar.bz2
rneovim-2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17.zip
rpc: Don't delay notifications when request is pending (#6544)
With the old behavior, if a GUI makes a blocking request that requires user interaction (like nvim_input()), it would not get any screen updates. The client, not nvim, should decide how to handle notifications during a pending request. If an rplugin wants to avoid async calls while a sync call is busy, it likely wants to avoid processing async calls while another async call also is handled as well. This may break the expectation of some existing rplugins. For compatibility, remote/define.vim reimplements the old behavior. Clients can opt-out by specifying `sync=urgent`. - Legacy hosts should be updated to use `sync=urgent`. They could add a flag indicating which async methods are always safe to call and which must wait until the main loop returns. - New hosts can expose the full asyncness, they don't need to offer both behaviors. ref #6532 ref #1398 d83868fe9071af1b4866594eac12f7aa0fa71b53
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py1
-rw-r--r--src/nvim/msgpack_rpc/channel.c36
2 files changed, 3 insertions, 34 deletions
diff --git a/src/clint.py b/src/clint.py
index 4a41650ec4..e63175a69b 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -2531,6 +2531,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
r'(?<!\bkhash_t)'
r'(?<!\bkbtree_t)'
r'(?<!\bkbitr_t)'
+ r'(?<!\bPMap)'
r'\((?:const )?(?:struct )?[a-zA-Z_]\w*(?: *\*(?:const)?)*\)'
r' +'
r'-?(?:\*+|&)?(?:\w+|\+\+|--|\()', cast_line)
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 88232a55de..5efdb9a194 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -56,7 +56,6 @@ typedef struct {
typedef struct {
uint64_t id;
size_t refcount;
- size_t pending_requests;
PMap(cstr_t) *subscribed_events;
bool closed;
ChannelType type;
@@ -71,7 +70,6 @@ typedef struct {
} data;
uint64_t next_request_id;
kvec_t(ChannelCallFrame *) call_stack;
- kvec_t(WBuffer *) delayed_notifications;
MultiQueue *events;
} Channel;
@@ -205,14 +203,7 @@ bool channel_send_event(uint64_t id, const char *name, Array args)
}
if (channel) {
- if (channel->pending_requests) {
- // Pending request, queue the notification for later sending.
- const String method = cstr_as_string((char *)name);
- WBuffer *buffer = serialize_request(id, 0, method, args, &out_buffer, 1);
- kv_push(channel->delayed_notifications, buffer);
- } else {
- send_event(channel, name, args);
- }
+ send_event(channel, name, args);
} else {
broadcast_event(name, args);
}
@@ -248,10 +239,8 @@ Object channel_send_call(uint64_t id,
// Push the frame
ChannelCallFrame frame = { request_id, false, false, NIL };
kv_push(channel->call_stack, &frame);
- channel->pending_requests++;
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1, frame.returned);
(void)kv_pop(channel->call_stack);
- channel->pending_requests--;
if (frame.errored) {
if (frame.result.type == kObjectTypeString) {
@@ -276,10 +265,6 @@ Object channel_send_call(uint64_t id,
api_free_object(frame.result);
}
- if (!channel->pending_requests) {
- send_delayed_notifications(channel);
- }
-
decref(channel);
return frame.errored ? NIL : frame.result;
@@ -704,11 +689,7 @@ static void broadcast_event(const char *name, Array args)
for (size_t i = 0; i < kv_size(subscribed); i++) {
Channel *channel = kv_A(subscribed, i);
- if (channel->pending_requests) {
- kv_push(channel->delayed_notifications, buffer);
- } else {
- channel_write(channel, buffer);
- }
+ channel_write(channel, buffer);
}
end:
@@ -786,7 +767,6 @@ static void free_channel(Channel *channel)
pmap_free(cstr_t)(channel->subscribed_events);
kv_destroy(channel->call_stack);
- kv_destroy(channel->delayed_notifications);
if (channel->type != kChannelTypeProc) {
multiqueue_free(channel->events);
}
@@ -811,11 +791,9 @@ static Channel *register_channel(ChannelType type, uint64_t id,
rv->closed = false;
rv->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
rv->id = id > 0 ? id : next_chan_id++;
- rv->pending_requests = 0;
rv->subscribed_events = pmap_new(cstr_t)();
rv->next_request_id = 1;
kv_init(rv->call_stack);
- kv_init(rv->delayed_notifications);
pmap_put(uint64_t)(channels, rv->id, rv);
ILOG("new channel %" PRIu64 " (%s): %s", rv->id,
@@ -912,16 +890,6 @@ static WBuffer *serialize_response(uint64_t channel_id,
return rv;
}
-static void send_delayed_notifications(Channel* channel)
-{
- for (size_t i = 0; i < kv_size(channel->delayed_notifications); i++) {
- WBuffer *buffer = kv_A(channel->delayed_notifications, i);
- channel_write(channel, buffer);
- }
-
- kv_size(channel->delayed_notifications) = 0;
-}
-
static void incref(Channel *channel)
{
channel->refcount++;