mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge PR #1978 'Prevent too early sending of delayed notifications.'
This commit is contained in:
commit
a5561fe610
@ -59,6 +59,7 @@ typedef struct {
|
|||||||
} data;
|
} data;
|
||||||
uint64_t next_request_id;
|
uint64_t next_request_id;
|
||||||
kvec_t(ChannelCallFrame *) call_stack;
|
kvec_t(ChannelCallFrame *) call_stack;
|
||||||
|
kvec_t(WBuffer *) delayed_notifications;
|
||||||
} Channel;
|
} Channel;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -68,18 +69,10 @@ typedef struct {
|
|||||||
uint64_t request_id;
|
uint64_t request_id;
|
||||||
} RequestEvent;
|
} RequestEvent;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Channel *channel;
|
|
||||||
String method;
|
|
||||||
Array args;
|
|
||||||
} DelayedNotification;
|
|
||||||
|
|
||||||
#define _noop(x)
|
#define _noop(x)
|
||||||
KMEMPOOL_INIT(RequestEventPool, RequestEvent, _noop)
|
KMEMPOOL_INIT(RequestEventPool, RequestEvent, _noop)
|
||||||
KLIST_INIT(DelayedNotification, DelayedNotification, _noop)
|
|
||||||
|
|
||||||
static kmempool_t(RequestEventPool) *request_event_pool = NULL;
|
static kmempool_t(RequestEventPool) *request_event_pool = NULL;
|
||||||
static klist_t(DelayedNotification) *delayed_notifications = NULL;
|
|
||||||
static uint64_t next_id = 1;
|
static uint64_t next_id = 1;
|
||||||
static PMap(uint64_t) *channels = NULL;
|
static PMap(uint64_t) *channels = NULL;
|
||||||
static PMap(cstr_t) *event_strings = NULL;
|
static PMap(cstr_t) *event_strings = NULL;
|
||||||
@ -93,7 +86,6 @@ static msgpack_sbuffer out_buffer;
|
|||||||
void channel_init(void)
|
void channel_init(void)
|
||||||
{
|
{
|
||||||
request_event_pool = kmp_init(RequestEventPool);
|
request_event_pool = kmp_init(RequestEventPool);
|
||||||
delayed_notifications = kl_init(DelayedNotification);
|
|
||||||
channels = pmap_new(uint64_t)();
|
channels = pmap_new(uint64_t)();
|
||||||
event_strings = pmap_new(cstr_t)();
|
event_strings = pmap_new(cstr_t)();
|
||||||
msgpack_sbuffer_init(&out_buffer);
|
msgpack_sbuffer_init(&out_buffer);
|
||||||
@ -191,13 +183,10 @@ bool channel_send_event(uint64_t id, char *name, Array args)
|
|||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
if (channel->pending_requests) {
|
if (channel->pending_requests) {
|
||||||
DelayedNotification p = {
|
// Pending request, queue the notification for later sending.
|
||||||
.channel = channel,
|
String method = cstr_as_string(name);
|
||||||
.method = cstr_to_string(name),
|
WBuffer *buffer = serialize_request(id, 0, method, args, &out_buffer, 1);
|
||||||
.args = args
|
kv_push(WBuffer *, channel->delayed_notifications, buffer);
|
||||||
};
|
|
||||||
// Pending request, queue the notification for sending later
|
|
||||||
*kl_pushp(DelayedNotification, delayed_notifications) = p;
|
|
||||||
} else {
|
} else {
|
||||||
send_event(channel, name, args);
|
send_event(channel, name, args);
|
||||||
}
|
}
|
||||||
@ -248,7 +237,7 @@ Object channel_send_call(uint64_t id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->pending_requests) {
|
if (!channel->pending_requests) {
|
||||||
send_delayed_notifications();
|
send_delayed_notifications(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
decref(channel);
|
decref(channel);
|
||||||
@ -506,6 +495,7 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
|
|||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
if (channel->closed) {
|
if (channel->closed) {
|
||||||
|
wstream_release_wbuffer(buffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,7 +583,12 @@ static void broadcast_event(char *name, Array args)
|
|||||||
kv_size(subscribed));
|
kv_size(subscribed));
|
||||||
|
|
||||||
for (size_t i = 0; i < kv_size(subscribed); i++) {
|
for (size_t i = 0; i < kv_size(subscribed); i++) {
|
||||||
channel_write(kv_A(subscribed, i), buffer);
|
Channel *channel = kv_A(subscribed, i);
|
||||||
|
if (channel->pending_requests) {
|
||||||
|
kv_push(WBuffer *, channel->delayed_notifications, buffer);
|
||||||
|
} else {
|
||||||
|
channel_write(channel, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@ -666,6 +661,7 @@ static void free_channel(Channel *channel)
|
|||||||
|
|
||||||
pmap_free(cstr_t)(channel->subscribed_events);
|
pmap_free(cstr_t)(channel->subscribed_events);
|
||||||
kv_destroy(channel->call_stack);
|
kv_destroy(channel->call_stack);
|
||||||
|
kv_destroy(channel->delayed_notifications);
|
||||||
free(channel);
|
free(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,6 +682,7 @@ static Channel *register_channel(void)
|
|||||||
rv->subscribed_events = pmap_new(cstr_t)();
|
rv->subscribed_events = pmap_new(cstr_t)();
|
||||||
rv->next_request_id = 1;
|
rv->next_request_id = 1;
|
||||||
kv_init(rv->call_stack);
|
kv_init(rv->call_stack);
|
||||||
|
kv_init(rv->delayed_notifications);
|
||||||
pmap_put(uint64_t)(channels, rv->id, rv);
|
pmap_put(uint64_t)(channels, rv->id, rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -773,18 +770,14 @@ static WBuffer *serialize_response(uint64_t channel_id,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_delayed_notifications(void)
|
static void send_delayed_notifications(Channel* channel)
|
||||||
{
|
{
|
||||||
DelayedNotification p;
|
for (size_t i = 0; i < kv_size(channel->delayed_notifications); i++) {
|
||||||
|
WBuffer *buffer = kv_A(channel->delayed_notifications, i);
|
||||||
while (kl_shift(DelayedNotification, delayed_notifications, &p) == 0) {
|
channel_write(channel, buffer);
|
||||||
if (p.channel) {
|
|
||||||
send_event(p.channel, p.method.data, p.args);
|
|
||||||
} else {
|
|
||||||
broadcast_event(p.method.data, p.args);
|
|
||||||
}
|
|
||||||
free(p.method.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kv_size(channel->delayed_notifications) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void incref(Channel *channel)
|
static void incref(Channel *channel)
|
||||||
|
@ -181,7 +181,7 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
release_wbuffer(buffer);
|
wstream_release_wbuffer(buffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ static void write_cb(uv_write_t *req, int status)
|
|||||||
|
|
||||||
data->wstream->curmem -= data->buffer->size;
|
data->wstream->curmem -= data->buffer->size;
|
||||||
|
|
||||||
release_wbuffer(data->buffer);
|
wstream_release_wbuffer(data->buffer);
|
||||||
|
|
||||||
if (data->wstream->cb) {
|
if (data->wstream->cb) {
|
||||||
data->wstream->cb(data->wstream,
|
data->wstream->cb(data->wstream,
|
||||||
@ -239,7 +239,7 @@ static void write_cb(uv_write_t *req, int status)
|
|||||||
kmp_free(WRequestPool, wrequest_pool, data);
|
kmp_free(WRequestPool, wrequest_pool, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_wbuffer(WBuffer *buffer)
|
void wstream_release_wbuffer(WBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (!--buffer->refcount) {
|
if (!--buffer->refcount) {
|
||||||
if (buffer->cb) {
|
if (buffer->cb) {
|
||||||
|
Loading…
Reference in New Issue
Block a user