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:
Thiago de Arruda
2014-06-17 10:01:44 -03:00
parent 0c764fb1a4
commit ac5fb407e4
4 changed files with 19 additions and 18 deletions

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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);
} }

View File

@@ -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