Skip to content
This repository has been archived by the owner on Nov 20, 2022. It is now read-only.

Commit

Permalink
Fix code to release read-write buffers after writes are completed. Fixes
Browse files Browse the repository at this point in the history
 #69.

Related to libuv/libuv#1072
  • Loading branch information
nikhilm committed Sep 29, 2016
1 parent af639ed commit 09dbd58
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
24 changes: 19 additions & 5 deletions code/multi-echo-server/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
uv_loop_t *loop;
uv_pipe_t queue;

typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;

void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = malloc(suggested_size);
buf->len = suggested_size;
Expand All @@ -17,20 +28,23 @@ void echo_write(uv_write_t *req, int status) {
if (status) {
fprintf(stderr, "Write error %s\n", uv_err_name(status));
}
free(req);
free_write_req(req);
}

void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init(buf->base, nread);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return;
}

if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, NULL);
return;
}

uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t));
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
uv_write(req, client, &wrbuf, 1, echo_write);
free(buf->base);
}

Expand Down
24 changes: 19 additions & 5 deletions code/pipe-echo-server/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@

uv_loop_t *loop;

typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;

void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = malloc(suggested_size);
buf->len = suggested_size;
Expand All @@ -14,20 +25,23 @@ void echo_write(uv_write_t *req, int status) {
if (status < 0) {
fprintf(stderr, "Write error %s\n", uv_err_name(status));
}
free(req);
free_write_req(req);
}

void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init(buf->base, nread);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return;
}

if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, NULL);
return;
}

uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t));
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
uv_write(req, client, &wrbuf, 1, echo_write);
free(buf->base);
}

Expand Down
26 changes: 19 additions & 7 deletions code/tcp-echo-server/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@
uv_loop_t *loop;
struct sockaddr_in addr;

typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;

void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char*) malloc(suggested_size);
buf->len = suggested_size;
Expand All @@ -18,22 +29,23 @@ void echo_write(uv_write_t *req, int status) {
if (status) {
fprintf(stderr, "Write error %s\n", uv_strerror(status));
}
free(req);
free_write_req(req);
}

void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init(buf->base, nread);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return;
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, NULL);
} else if (nread > 0) {
uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t));
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
uv_write(req, client, &wrbuf, 1, echo_write);
}

if (buf->base)
free(buf->base);
free(buf->base);
}

void on_new_connection(uv_stream_t *server, int status) {
Expand Down
1 change: 1 addition & 0 deletions code/uvtee/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
write_data((uv_stream_t *)&file_pipe, nread, *buf, on_file_write);
}

// OK to free buffer as write_data copies it.
if (buf->base)
free(buf->base);
}
Expand Down

0 comments on commit 09dbd58

Please sign in to comment.