mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Create EventType for RStream reading
RStream will be the main way Neovim receives asynchronous messages, so it is best to have a specialized EventType for it. A new flag parameter was added to `rstream_new` which tells the RStream instance to defer event handling for later with KE_EVENT instead of handling it directly from libuv callback.
This commit is contained in:
parent
c40428c934
commit
350144f511
@ -8,6 +8,7 @@
|
|||||||
#include "os/event.h"
|
#include "os/event.h"
|
||||||
#include "os/input.h"
|
#include "os/input.h"
|
||||||
#include "os/signal.h"
|
#include "os/signal.h"
|
||||||
|
#include "os/rstream.h"
|
||||||
#include "os/job.h"
|
#include "os/job.h"
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@ -112,6 +113,9 @@ void event_process()
|
|||||||
case kEventJobActivity:
|
case kEventJobActivity:
|
||||||
job_handle(event);
|
job_handle(event);
|
||||||
break;
|
break;
|
||||||
|
case kEventRStreamData:
|
||||||
|
rstream_read_event(event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,18 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kEventSignal,
|
kEventSignal,
|
||||||
kEventJobActivity
|
kEventJobActivity,
|
||||||
|
kEventRStreamData
|
||||||
} EventType;
|
} EventType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EventType type;
|
EventType type;
|
||||||
union {
|
union {
|
||||||
int signum;
|
int signum;
|
||||||
|
struct {
|
||||||
|
RStream *ptr;
|
||||||
|
bool eof;
|
||||||
|
} rstream;
|
||||||
struct {
|
struct {
|
||||||
Job *ptr;
|
Job *ptr;
|
||||||
RStream *target;
|
RStream *target;
|
||||||
|
@ -34,7 +34,7 @@ static int push_event_key(uint8_t *buf, int maxlen);
|
|||||||
|
|
||||||
void input_init()
|
void input_init()
|
||||||
{
|
{
|
||||||
read_stream = rstream_new(read_cb, READ_BUFFER_SIZE, NULL);
|
read_stream = rstream_new(read_cb, READ_BUFFER_SIZE, NULL, false);
|
||||||
rstream_set_file(read_stream, read_cmd_fd);
|
rstream_set_file(read_stream, read_cmd_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ int job_start(char **argv, void *data, job_read_cb cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start the readable streams
|
// Start the readable streams
|
||||||
job->out = rstream_new(read_cb, JOB_BUFFER_SIZE, job);
|
job->out = rstream_new(read_cb, JOB_BUFFER_SIZE, job, false);
|
||||||
job->err = rstream_new(read_cb, JOB_BUFFER_SIZE, job);
|
job->err = rstream_new(read_cb, JOB_BUFFER_SIZE, job, false);
|
||||||
rstream_set_stream(job->out, (uv_stream_t *)&job->proc_stdout);
|
rstream_set_stream(job->out, (uv_stream_t *)&job->proc_stdout);
|
||||||
rstream_set_stream(job->err, (uv_stream_t *)&job->proc_stderr);
|
rstream_set_stream(job->err, (uv_stream_t *)&job->proc_stderr);
|
||||||
rstream_start(job->out);
|
rstream_start(job->out);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "os/event_defs.h"
|
||||||
#include "os/event.h"
|
#include "os/event.h"
|
||||||
|
|
||||||
/// Initializes job control resources
|
/// Initializes job control resources
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "os/rstream_defs.h"
|
#include "os/rstream_defs.h"
|
||||||
#include "os/rstream.h"
|
#include "os/rstream.h"
|
||||||
|
#include "os/event_defs.h"
|
||||||
|
#include "os/event.h"
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
@ -19,20 +21,25 @@ struct rstream {
|
|||||||
uv_file fd;
|
uv_file fd;
|
||||||
rstream_cb cb;
|
rstream_cb cb;
|
||||||
uint32_t buffer_size, rpos, wpos, fpos;
|
uint32_t buffer_size, rpos, wpos, fpos;
|
||||||
bool reading, free_handle;
|
bool reading, free_handle, async;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callbacks used by libuv
|
// Callbacks used by libuv
|
||||||
static void alloc_cb(uv_handle_t *, size_t, uv_buf_t *);
|
static void alloc_cb(uv_handle_t *, size_t, uv_buf_t *);
|
||||||
static void read_cb(uv_stream_t *, ssize_t, const uv_buf_t *);
|
static void read_cb(uv_stream_t *, ssize_t, const uv_buf_t *);
|
||||||
static void fread_idle_cb(uv_idle_t *);
|
static void fread_idle_cb(uv_idle_t *);
|
||||||
|
static void emit_read_event(RStream *rstream, bool eof);
|
||||||
|
|
||||||
RStream * rstream_new(rstream_cb cb, uint32_t buffer_size, void *data)
|
RStream * rstream_new(rstream_cb cb,
|
||||||
|
uint32_t buffer_size,
|
||||||
|
void *data,
|
||||||
|
bool async)
|
||||||
{
|
{
|
||||||
RStream *rv = xmalloc(sizeof(RStream));
|
RStream *rv = xmalloc(sizeof(RStream));
|
||||||
rv->buffer = xmalloc(buffer_size);
|
rv->buffer = xmalloc(buffer_size);
|
||||||
rv->buffer_size = buffer_size;
|
rv->buffer_size = buffer_size;
|
||||||
rv->data = data;
|
rv->data = data;
|
||||||
|
rv->async = async;
|
||||||
rv->cb = cb;
|
rv->cb = cb;
|
||||||
rv->rpos = rv->wpos = rv->fpos = 0;
|
rv->rpos = rv->wpos = rv->fpos = 0;
|
||||||
rv->stream = NULL;
|
rv->stream = NULL;
|
||||||
@ -162,6 +169,13 @@ uint32_t rstream_available(RStream *rstream)
|
|||||||
return rstream->wpos - rstream->rpos;
|
return rstream->wpos - rstream->rpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rstream_read_event(Event event)
|
||||||
|
{
|
||||||
|
RStream *rstream = event.data.rstream.ptr;
|
||||||
|
|
||||||
|
rstream->cb(rstream, rstream->data, event.data.rstream.eof);
|
||||||
|
}
|
||||||
|
|
||||||
// Called by libuv to allocate memory for reading.
|
// Called by libuv to allocate memory for reading.
|
||||||
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
|
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
|
||||||
{
|
{
|
||||||
@ -191,7 +205,7 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
|
|||||||
// Read error or EOF, either way stop the stream and invoke the callback
|
// Read error or EOF, either way stop the stream and invoke the callback
|
||||||
// with eof == true
|
// with eof == true
|
||||||
uv_read_stop(stream);
|
uv_read_stop(stream);
|
||||||
rstream->cb(rstream, rstream->data, true);
|
emit_read_event(rstream, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -205,11 +219,8 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
|
|||||||
rstream_stop(rstream);
|
rstream_stop(rstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the callback passing in the number of bytes available and data
|
|
||||||
// associated with the stream
|
|
||||||
rstream->cb(rstream, rstream->data, false);
|
|
||||||
rstream->reading = false;
|
rstream->reading = false;
|
||||||
|
emit_read_event(rstream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the by the 'idle' handle to emulate a reading event
|
// Called by the by the 'idle' handle to emulate a reading event
|
||||||
@ -235,7 +246,7 @@ static void fread_idle_cb(uv_idle_t *handle)
|
|||||||
|
|
||||||
if (req.result <= 0) {
|
if (req.result <= 0) {
|
||||||
uv_idle_stop(rstream->fread_idle);
|
uv_idle_stop(rstream->fread_idle);
|
||||||
rstream->cb(rstream, rstream->data, true);
|
emit_read_event(rstream, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,5 +258,21 @@ static void fread_idle_cb(uv_idle_t *handle)
|
|||||||
rstream_stop(rstream);
|
rstream_stop(rstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
rstream->cb(rstream, rstream->data, false);
|
emit_read_event(rstream, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_read_event(RStream *rstream, bool eof)
|
||||||
|
{
|
||||||
|
if (rstream->async) {
|
||||||
|
Event event;
|
||||||
|
|
||||||
|
event.type = kEventRStreamData;
|
||||||
|
event.data.rstream.ptr = rstream;
|
||||||
|
event.data.rstream.eof = eof;
|
||||||
|
event_push(event);
|
||||||
|
} else {
|
||||||
|
// Invoke the callback passing in the number of bytes available and data
|
||||||
|
// associated with the stream
|
||||||
|
rstream->cb(rstream, rstream->data, eof);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
#include "os/event_defs.h"
|
||||||
#include "os/rstream_defs.h"
|
#include "os/rstream_defs.h"
|
||||||
|
|
||||||
/// Creates a new RStream instance. A RStream encapsulates all the boilerplate
|
/// Creates a new RStream instance. A RStream encapsulates all the boilerplate
|
||||||
@ -14,8 +15,15 @@
|
|||||||
/// for reading with `rstream_read`
|
/// for reading with `rstream_read`
|
||||||
/// @param buffer_size Size in bytes of the internal buffer.
|
/// @param buffer_size Size in bytes of the internal buffer.
|
||||||
/// @param data Some state to associate with the `RStream` instance
|
/// @param data Some state to associate with the `RStream` instance
|
||||||
|
/// @param async Flag that specifies if the callback should only be called
|
||||||
|
/// outside libuv event loop(When processing async events with
|
||||||
|
/// KE_EVENT). Only the RStream instance reading user input should set
|
||||||
|
/// this to false
|
||||||
/// @return The newly-allocated `RStream` instance
|
/// @return The newly-allocated `RStream` instance
|
||||||
RStream * rstream_new(rstream_cb cb, uint32_t buffer_size, void *data);
|
RStream * rstream_new(rstream_cb cb,
|
||||||
|
uint32_t buffer_size,
|
||||||
|
void *data,
|
||||||
|
bool async);
|
||||||
|
|
||||||
/// Frees all memory allocated for a RStream instance
|
/// Frees all memory allocated for a RStream instance
|
||||||
///
|
///
|
||||||
@ -71,5 +79,10 @@ uint32_t rstream_read(RStream *rstream, char *buffer, uint32_t count);
|
|||||||
/// @return The number of bytes available
|
/// @return The number of bytes available
|
||||||
uint32_t rstream_available(RStream *rstream);
|
uint32_t rstream_available(RStream *rstream);
|
||||||
|
|
||||||
|
/// Runs the read callback associated with the rstream
|
||||||
|
///
|
||||||
|
/// @param event Object containing data necessary to invoke the callback
|
||||||
|
void rstream_read_event(Event event);
|
||||||
|
|
||||||
#endif // NEOVIM_OS_RSTREAM_H
|
#endif // NEOVIM_OS_RSTREAM_H
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user