mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 13:38:34 +00:00
wstream: Refactor wstream_new_buffer/wstream_write
- Removed 'copy' parameter from `wstream_new_buffer`. Callers simply pass a copy of the buffer if required. - Added a callback parameter, which is used to notify callers when the data is successfully written. The callback is also used to free the buffer(if required) and is compatible with `free` from the standard library.
This commit is contained in:
@@ -194,9 +194,10 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
|||||||
// Perform the call
|
// Perform the call
|
||||||
msgpack_rpc_call(channel->id, &unpacked.data, &response);
|
msgpack_rpc_call(channel->id, &unpacked.data, &response);
|
||||||
wstream_write(channel->data.streams.write,
|
wstream_write(channel->data.streams.write,
|
||||||
wstream_new_buffer(channel->sbuffer->data,
|
wstream_new_buffer(xmemdup(channel->sbuffer->data,
|
||||||
|
channel->sbuffer->size),
|
||||||
channel->sbuffer->size,
|
channel->sbuffer->size,
|
||||||
true));
|
free));
|
||||||
|
|
||||||
// Clear the buffer for future calls
|
// Clear the buffer for future calls
|
||||||
msgpack_sbuffer_clear(channel->sbuffer);
|
msgpack_sbuffer_clear(channel->sbuffer);
|
||||||
@@ -218,9 +219,10 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
|||||||
"an object with high level of nesting",
|
"an object with high level of nesting",
|
||||||
&response);
|
&response);
|
||||||
wstream_write(channel->data.streams.write,
|
wstream_write(channel->data.streams.write,
|
||||||
wstream_new_buffer(channel->sbuffer->data,
|
wstream_new_buffer(xmemdup(channel->sbuffer->data,
|
||||||
|
channel->sbuffer->size),
|
||||||
channel->sbuffer->size,
|
channel->sbuffer->size,
|
||||||
true));
|
free));
|
||||||
// Clear the buffer for future calls
|
// Clear the buffer for future calls
|
||||||
msgpack_sbuffer_clear(channel->sbuffer);
|
msgpack_sbuffer_clear(channel->sbuffer);
|
||||||
}
|
}
|
||||||
@@ -310,9 +312,10 @@ static WBuffer *serialize_event(char *type, typval_T *data)
|
|||||||
msgpack_packer packer;
|
msgpack_packer packer;
|
||||||
msgpack_packer_init(&packer, &msgpack_event_buffer, msgpack_sbuffer_write);
|
msgpack_packer_init(&packer, &msgpack_event_buffer, msgpack_sbuffer_write);
|
||||||
msgpack_rpc_notification(event_type, event_data, &packer);
|
msgpack_rpc_notification(event_type, event_data, &packer);
|
||||||
WBuffer *rv = wstream_new_buffer(msgpack_event_buffer.data,
|
WBuffer *rv = wstream_new_buffer(xmemdup(msgpack_event_buffer.data,
|
||||||
|
msgpack_event_buffer.size),
|
||||||
msgpack_event_buffer.size,
|
msgpack_event_buffer.size,
|
||||||
true);
|
free);
|
||||||
msgpack_rpc_free_object(event_data);
|
msgpack_rpc_free_object(event_data);
|
||||||
msgpack_sbuffer_clear(&msgpack_event_buffer);
|
msgpack_sbuffer_clear(&msgpack_event_buffer);
|
||||||
|
|
||||||
|
@@ -258,7 +258,7 @@ bool job_write(int id, char *data, uint32_t len)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wstream_write(job->in, wstream_new_buffer(data, len, false))) {
|
if (!wstream_write(job->in, wstream_new_buffer(data, len, free))) {
|
||||||
job_stop(job->id);
|
job_stop(job->id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,9 @@ struct wstream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct wbuffer {
|
struct wbuffer {
|
||||||
size_t refcount, size;
|
size_t size, refcount;
|
||||||
char *data;
|
char *data;
|
||||||
|
wbuffer_data_finalizer cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -116,19 +117,16 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
|
|||||||
///
|
///
|
||||||
/// @param data Data stored by the WBuffer
|
/// @param data Data stored by the WBuffer
|
||||||
/// @param size The size of the data array
|
/// @param size The size of the data array
|
||||||
/// @param copy If true, the data will be copied into the WBuffer
|
/// @param cb Pointer to function that will be responsible for freeing
|
||||||
|
/// the buffer data(passing 'free' will work as expected).
|
||||||
/// @return The allocated WBuffer instance
|
/// @return The allocated WBuffer instance
|
||||||
WBuffer *wstream_new_buffer(char *data, size_t size, bool copy)
|
WBuffer *wstream_new_buffer(char *data, size_t size, wbuffer_data_finalizer cb)
|
||||||
{
|
{
|
||||||
WBuffer *rv = xmalloc(sizeof(WBuffer));
|
WBuffer *rv = xmalloc(sizeof(WBuffer));
|
||||||
rv->size = size;
|
rv->size = size;
|
||||||
rv->refcount = 0;
|
rv->refcount = 0;
|
||||||
|
rv->cb = cb;
|
||||||
if (copy) {
|
rv->data = data;
|
||||||
rv->data = xmemdup(data, size);
|
|
||||||
} else {
|
|
||||||
rv->data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -141,8 +139,7 @@ static void write_cb(uv_write_t *req, int status)
|
|||||||
data->wstream->curmem -= data->buffer->size;
|
data->wstream->curmem -= data->buffer->size;
|
||||||
|
|
||||||
if (!--data->buffer->refcount) {
|
if (!--data->buffer->refcount) {
|
||||||
// Free the data written to the stream
|
data->buffer->cb(data->buffer->data);
|
||||||
free(data->buffer->data);
|
|
||||||
free(data->buffer);
|
free(data->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
typedef struct wbuffer WBuffer;
|
typedef struct wbuffer WBuffer;
|
||||||
typedef struct wstream WStream;
|
typedef struct wstream WStream;
|
||||||
|
typedef void (*wbuffer_data_finalizer)(void *data);
|
||||||
|
|
||||||
#endif // NVIM_OS_WSTREAM_DEFS_H
|
#endif // NVIM_OS_WSTREAM_DEFS_H
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user