aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/wstream.c
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-05-27 09:12:53 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-05-28 08:52:54 -0300
commit09bcd97023e68943a82995f8f13cf0c984a9bb5f (patch)
tree7867fba0b2af4ce4d9ea1a726c4319756afa8aeb /src/nvim/os/wstream.c
parent1c308e28f1b52682034b97e89f2b3e76fb3c913f (diff)
downloadrneovim-09bcd97023e68943a82995f8f13cf0c984a9bb5f.tar.gz
rneovim-09bcd97023e68943a82995f8f13cf0c984a9bb5f.tar.bz2
rneovim-09bcd97023e68943a82995f8f13cf0c984a9bb5f.zip
WStream: Refactor: Use reference count for memory management
Now `wstream_write` receives pointers for WBuffer objects(created with wstream_new_buffer), which stores a reference count to determine when it's safe the free the buffer. This was done to enable writing of the same buffer to multiple WStream instances
Diffstat (limited to 'src/nvim/os/wstream.c')
-rw-r--r--src/nvim/os/wstream.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/src/nvim/os/wstream.c b/src/nvim/os/wstream.c
index 22524e2430..57afdd0e8f 100644
--- a/src/nvim/os/wstream.c
+++ b/src/nvim/os/wstream.c
@@ -20,14 +20,14 @@ struct wstream {
bool freed;
};
+struct wbuffer {
+ size_t refcount, size;
+ char *data;
+};
+
typedef struct {
WStream *wstream;
- // Buffer containing data to be written
- char *buffer;
- // Size of the buffer
- size_t length;
- // If it's our responsibility to free the buffer
- bool free;
+ WBuffer *buffer;
} WriteData;
static void write_cb(uv_write_t *req, int status);
@@ -59,51 +59,60 @@ void wstream_set_stream(WStream *wstream, uv_stream_t *stream)
wstream->stream = stream;
}
-bool wstream_write(WStream *wstream, char *buffer, size_t length, bool free)
+bool wstream_write(WStream *wstream, WBuffer *buffer)
{
WriteData *data;
uv_buf_t uvbuf;
uv_write_t *req;
- if (wstream->freed) {
- // Don't accept write requests after the WStream instance was freed
- return false;
- }
+ // This should not be called after a wstream was freed
+ assert(!wstream->freed);
- if (wstream->curmem + length > wstream->maxmem) {
+ if (wstream->curmem + buffer->size > wstream->maxmem) {
return false;
}
- if (free) {
- // We should only account for buffers that are ours to free
- wstream->curmem += length;
- }
-
+ buffer->refcount++;
+ wstream->curmem += buffer->size;
data = xmalloc(sizeof(WriteData));
data->wstream = wstream;
data->buffer = buffer;
- data->length = length;
- data->free = free;
req = xmalloc(sizeof(uv_write_t));
req->data = data;
- uvbuf.base = buffer;
- uvbuf.len = length;
+ uvbuf.base = buffer->data;
+ uvbuf.len = buffer->size;
wstream->pending_reqs++;
uv_write(req, wstream->stream, &uvbuf, 1, write_cb);
return true;
}
+WBuffer *wstream_new_buffer(char *data, size_t size, bool copy)
+{
+ WBuffer *rv = xmalloc(sizeof(WBuffer));
+ rv->size = size;
+ rv->refcount = 0;
+
+ if (copy) {
+ rv->data = xmemdup(data, size);
+ } else {
+ rv->data = data;
+ }
+
+ return rv;
+}
+
static void write_cb(uv_write_t *req, int status)
{
WriteData *data = req->data;
free(req);
+ data->wstream->curmem -= data->buffer->size;
- if (data->free) {
+ if (!--data->buffer->refcount) {
// Free the data written to the stream
+ free(data->buffer->data);
free(data->buffer);
- data->wstream->curmem -= data->length;
}
data->wstream->pending_reqs--;