diff options
author | Fedor Indutny <fedor@indutny.com> | 2016-05-26 03:42:56 -0400 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2016-05-26 03:42:56 -0400 |
commit | f3be4240e5da100f7615e6805648ed50485c2ebb (patch) | |
tree | 1ab9b525bdf3f47a53d49602a0383548861906b6 | |
parent | e6061e7dbcc1ac16222f2c44c467cf5e7a3f31ad (diff) | |
download | uv_link_t-f3be4240e5da100f7615e6805648ed50485c2ebb.tar.gz |
example: initial
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | example/example.gyp | 20 | ||||
-rw-r--r-- | example/src/main.c | 99 | ||||
-rw-r--r-- | example/src/middle.c | 58 | ||||
-rw-r--r-- | example/src/middle.h | 6 | ||||
-rwxr-xr-x | gyp_uv_link | 9 | ||||
-rw-r--r-- | include/uv_link_t.h | 11 | ||||
-rw-r--r-- | src/uv_link_observer_t.c | 8 | ||||
-rw-r--r-- | src/uv_link_t.c | 9 |
9 files changed, 210 insertions, 17 deletions
diff --git a/README.md b/README.md index a8db41a..14f6963 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,12 @@ static uv_link_methods_t methods = { .read_stop = read_stop_impl, .write = write_impl, .try_write = try_write_impl, - .shutdown = shutdown_impl + .shutdown = shutdown_impl, + + /* These will be used only when chaining two links together */ + + .alloc_cb_override = alloc_cb_impl, + .read_cb_override = read_cb_impl }; uv_link_init(&link, &methods); diff --git a/example/example.gyp b/example/example.gyp new file mode 100644 index 0000000..a3dc597 --- /dev/null +++ b/example/example.gyp @@ -0,0 +1,20 @@ +{ + "targets": [{ + "target_name": "uv_link_t-example", + "type": "executable", + + "include_dirs": [ + "src" + ], + + "dependencies": [ + "../test/deps/libuv/uv.gyp:libuv", + "../uv_link_t.gyp:uv_link_t" + ], + + "sources": [ + "src/main.c", + "src/middle.c", + ], + }], +} diff --git a/example/src/main.c b/example/src/main.c new file mode 100644 index 0000000..4fa570f --- /dev/null +++ b/example/src/main.c @@ -0,0 +1,99 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "uv.h" +#include "uv_link_t.h" + +/* Declaration of `middle_methods` */ +#include "middle.h" + +typedef struct client_s client_t; + +static uv_tcp_t server; + +struct client_s { + uv_tcp_t tcp; + uv_link_source_t source; + uv_link_t middle; + uv_link_observer_t observer; +}; + +static void read_cb(uv_link_observer_t* observer, + ssize_t nread, + const uv_buf_t* buf) { + client_t* client; + + client = observer->link.data; + + if (nread < 0) { + fprintf(stderr, "error or close\n"); + uv_link_read_stop(&observer->link); + uv_close((uv_handle_t*) &client->tcp, NULL); + free(client); + return; + } + + fprintf(stderr, "read \"%.*s\"\n", (int) nread, buf->base); +} + + +static void connection_cb(uv_stream_t* s, int status) { + int err; + client_t* client; + + client = malloc(sizeof(*client)); + assert(client != NULL); + + err = uv_tcp_init(uv_default_loop(), &client->tcp); + assert(err == 0); + + err = uv_accept(s, (uv_stream_t*) &client->tcp); + assert(err == 0); + + err = uv_link_source_init(&client->source, (uv_stream_t*) &client->tcp); + assert(err == 0); + + err = uv_link_init(&client->middle, &middle_methods); + assert(err == 0); + + err = uv_link_chain(&client->source.link, &client->middle); + assert(err == 0); + + err = uv_link_observer_init(&client->observer, &client->middle); + assert(err == 0); + + client->observer.read_cb = read_cb; + client->observer.link.data = client; + + err = uv_link_read_start(&client->observer.link); + assert(err == 0); +} + + +int main() { + static const int kBacklog = 128; + + int err; + uv_loop_t* loop; + struct sockaddr_in addr; + + loop = uv_default_loop(); + + err = uv_tcp_init(loop, &server); + assert(err == 0); + + err = uv_ip4_addr("0.0.0.0", 9000, &addr); + assert(err == 0); + + err = uv_tcp_bind(&server, (struct sockaddr*) &addr, 0); + assert(err == 0); + + err = uv_listen((uv_stream_t*) &server, kBacklog, connection_cb); + + err = uv_run(loop, UV_RUN_DEFAULT); + assert(err == 0); + + return 0; +} diff --git a/example/src/middle.c b/example/src/middle.c new file mode 100644 index 0000000..9e6d158 --- /dev/null +++ b/example/src/middle.c @@ -0,0 +1,58 @@ +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "uv_link_t.h" + +static int read_start_impl(uv_link_t* link) { + return uv_link_read_start(link->parent); +} + + +static int read_stop_impl(uv_link_t* link) { + return uv_link_read_stop(link->parent); +} + + +static void alloc_cb_override(uv_link_t* link, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + assert(buf->base != NULL); + buf->len = suggested_size; +} + + +static void read_cb_override(uv_link_t* link, + ssize_t nread, + const uv_buf_t* buf) { + const char* res; + uv_buf_t tmp; + + if (nread >= 0) { + if (nread == 9 && strncmp(buf->base, "password\n", 9) == 0) + res = "welcome"; + else + res = "go away"; + } else { + res = "error"; + } + + free(buf->base); + + uv_link_invoke_alloc_cb(link, strlen(res), &tmp); + assert(tmp.len >= strlen(res)); + + memcpy(tmp.base, res, strlen(res)); + uv_link_invoke_read_cb(link, strlen(res), &tmp); +} + + +uv_link_methods_t middle_methods = { + .read_start = read_start_impl, + .read_stop = read_stop_impl, + + /* Other doesn't matter in this example */ + .alloc_cb_override = alloc_cb_override, + .read_cb_override = read_cb_override +}; diff --git a/example/src/middle.h b/example/src/middle.h new file mode 100644 index 0000000..820721d --- /dev/null +++ b/example/src/middle.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_SRC_MIDDLE_H_ +#define EXAMPLE_SRC_MIDDLE_H_ + +uv_link_methods_t middle_methods; + +#endif /* EXAMPLE_SRC_MIDDLE_H_ */ diff --git a/gyp_uv_link b/gyp_uv_link index 73251d6..35ae446 100755 --- a/gyp_uv_link +++ b/gyp_uv_link @@ -52,11 +52,14 @@ def run_gyp(args): if __name__ == '__main__': args = sys.argv[1:] - if 'test' not in args: - args.append(os.path.join(os.path.abspath(root), 'uv_link_t.gyp')) - else: + if 'test' in args: args.append(os.path.join(os.path.abspath(root), 'test/test.gyp')) args = filter(lambda arg: arg != 'test', args) + elif 'example' in args: + args.append(os.path.join(os.path.abspath(root), 'example/example.gyp')) + args = filter(lambda arg: arg != 'example', args) + else: + args.append(os.path.join(os.path.abspath(root), 'uv_link_t.gyp')) common_fn = os.path.join(os.path.abspath(root), 'common.gypi') options_fn = os.path.join(os.path.abspath(root), 'options.gypi') diff --git a/include/uv_link_t.h b/include/uv_link_t.h index 738c19f..919d5ec 100644 --- a/include/uv_link_t.h +++ b/include/uv_link_t.h @@ -31,6 +31,10 @@ struct uv_link_methods_s { unsigned int nbufs); int (*shutdown)(uv_link_t* link, uv_link_shutdown_cb cb); + + /* Overriding callbacks */ + uv_link_alloc_cb alloc_cb_override; + uv_link_read_cb read_cb_override; }; struct uv_link_s { @@ -40,6 +44,8 @@ struct uv_link_s { uv_link_alloc_cb alloc_cb; uv_link_read_cb read_cb; + void* data; + /* Read-only after assigning initial values */ /* Sort of virtual table */ @@ -53,10 +59,7 @@ struct uv_link_s { UV_EXTERN int uv_link_init(uv_link_t* link, uv_link_methods_t const* methods); UV_EXTERN void uv_link_close(uv_link_t* link); -UV_EXTERN int uv_link_chain(uv_link_t* from, - uv_link_t* to, - uv_link_alloc_cb alloc_cb, - uv_link_read_cb read_cb); +UV_EXTERN int uv_link_chain(uv_link_t* from, uv_link_t* to); UV_EXTERN int uv_link_unchain(uv_link_t* from, uv_link_t* to); /* Use this to invoke methods */ diff --git a/src/uv_link_observer_t.c b/src/uv_link_observer_t.c index cd389f6..3ce0df9 100644 --- a/src/uv_link_observer_t.c +++ b/src/uv_link_observer_t.c @@ -81,7 +81,10 @@ static uv_link_methods_t uv_link_observer_methods = { .read_stop = uv_link_observer_read_stop, .write = uv_link_observer_write, .try_write = uv_link_observer_try_write, - .shutdown = uv_link_observer_shutdown + .shutdown = uv_link_observer_shutdown, + + .alloc_cb_override = uv_link_observer_alloc_cb, + .read_cb_override = uv_link_observer_read_cb }; @@ -97,8 +100,7 @@ int uv_link_observer_init(uv_link_observer_t* observer, observer->target = target; - err = uv_link_chain(target, &observer->link, uv_link_observer_alloc_cb, - uv_link_observer_read_cb); + err = uv_link_chain(target, &observer->link); if (err != 0) { uv_link_close(&observer->link); return err; diff --git a/src/uv_link_t.c b/src/uv_link_t.c index 769b269..fc6eabc 100644 --- a/src/uv_link_t.c +++ b/src/uv_link_t.c @@ -41,10 +41,7 @@ void uv_link_close(uv_link_t* link) { } -int uv_link_chain(uv_link_t* from, - uv_link_t* to, - uv_link_alloc_cb alloc_cb, - uv_link_read_cb read_cb) { +int uv_link_chain(uv_link_t* from, uv_link_t* to) { if (from->child != NULL || to->parent != NULL) return UV_EINVAL; @@ -53,8 +50,8 @@ int uv_link_chain(uv_link_t* from, from->saved_alloc_cb = from->alloc_cb; from->saved_read_cb = from->read_cb; - from->alloc_cb = alloc_cb; - from->read_cb = read_cb; + from->alloc_cb = to->methods->alloc_cb_override; + from->read_cb = to->methods->read_cb_override; return 0; } |