From: Niels Provos Date: Wed, 23 May 2007 05:20:59 +0000 (+0000) Subject: support removing of http callbacks and removing of registered RPCs X-Git-Tag: release-2.0.1-alpha~626 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c2808246a5db1515f0392ef6f65a557e5832ccb;p=libevent support removing of http callbacks and removing of registered RPCs svn:r355 --- diff --git a/buffer.c b/buffer.c index 53c0bf8c..6b558a83 100644 --- a/buffer.c +++ b/buffer.c @@ -44,6 +44,7 @@ #include #endif +#include #include #include #include @@ -134,9 +135,13 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) int sz; va_list aq; + /* make sure that at least some space is available */ + evbuffer_expand(buf, 64); for (;;) { + size_t used = buf->misalign + buf->off; buffer = (char *)buf->buffer + buf->off; - space = buf->totallen - buf->misalign - buf->off; + assert(buf->totallen >= used); + space = buf->totallen - used; #ifndef va_copy #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) @@ -152,7 +157,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) va_end(aq); - if (sz == -1) + if (sz < 0) return (-1); if (sz < space) { buf->off += sz; diff --git a/evhttp.h b/evhttp.h index 3477b763..16744163 100644 --- a/evhttp.h +++ b/evhttp.h @@ -75,6 +75,9 @@ void evhttp_free(struct evhttp* http); void evhttp_set_cb(struct evhttp *, const char *, void (*)(struct evhttp_request *, void *), void *); +/* Removes the callback for a specified URI */ +int evhttp_del_cb(struct evhttp *, const char *); + /* Set a callback for all requests that are not caught by specific callbacks */ void evhttp_set_gencb(struct evhttp *, void (*)(struct evhttp_request *, void *), void *); diff --git a/evrpc.c b/evrpc.c index d575cd14..0d3e014d 100644 --- a/evrpc.c +++ b/evrpc.c @@ -133,6 +133,35 @@ evrpc_register_rpc(struct evrpc_base *base, struct evrpc *rpc, return (0); } +int +evrpc_unregister_rpc(struct evrpc_base *base, const char *name) +{ + char *registered_uri = NULL; + struct evrpc *rpc; + + /* find the right rpc; linear search might be slow */ + TAILQ_FOREACH(rpc, &base->registered_rpcs, next) { + if (strcmp(rpc->uri, name) == 0) + break; + } + if (rpc == NULL) { + /* We did not find an RPC with this name */ + return (-1); + } + TAILQ_REMOVE(&base->registered_rpcs, rpc, next); + + free((char *)rpc->uri); + free(rpc); + + registered_uri = evrpc_construct_uri(name); + + /* remove the http server callback */ + assert(evhttp_del_cb(base->http_server, registered_uri) == 0); + + free(registered_uri); + return (0); +} + static void evrpc_request_cb(struct evhttp_request *req, void *arg) { diff --git a/evrpc.h b/evrpc.h index fc452623..5ec5ff84 100644 --- a/evrpc.h +++ b/evrpc.h @@ -223,6 +223,11 @@ struct evrpc_base *evrpc_init(struct evhttp *server); int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, void (*)(struct evrpc_req_generic*, void *), void *); +/* Takes the named RPCs and tried to unregister it */ +#define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc(base, #name) + +int evrpc_unregister_rpc(struct evrpc_base *, const char *name); + /* * Client-side RPC support */ diff --git a/http.c b/http.c index 20ab4641..e69c33a5 100644 --- a/http.c +++ b/http.c @@ -1976,6 +1976,25 @@ evhttp_set_cb(struct evhttp *http, const char *uri, TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next); } +int +evhttp_del_cb(struct evhttp *http, const char *uri) +{ + struct evhttp_cb *http_cb; + + TAILQ_FOREACH(http_cb, &http->callbacks, next) { + if (strcmp(http_cb->what, uri) == 0) + break; + } + if (http_cb == NULL) + return (-1); + + TAILQ_REMOVE(&http->callbacks, http_cb, next); + free(http_cb->what); + free(http_cb); + + return (0); +} + void evhttp_set_gencb(struct evhttp *http, void (*cb)(struct evhttp_request *, void *), void *cbarg) diff --git a/test/regress_rpc.c b/test/regress_rpc.c index dcae9c9e..7a346ac4 100644 --- a/test/regress_rpc.c +++ b/test/regress_rpc.c @@ -128,6 +128,13 @@ rpc_setup(struct evhttp **phttp, short *pport, struct evrpc_base **pbase) *pbase = base; } +static void +rpc_teardown(struct evrpc_base *base) +{ + assert(EVRPC_UNREGISTER(base, Message) == 0); + assert(EVRPC_UNREGISTER(base, NeverReply) == 0); +} + static void rpc_postrequest_failure(struct evhttp_request *req, void *arg) { @@ -189,6 +196,8 @@ rpc_basic_test(void) test_ok = 0; event_dispatch(); + + rpc_teardown(base); if (test_ok != 1) { fprintf(stdout, "FAILED\n"); @@ -276,6 +285,8 @@ rpc_basic_message(void) event_dispatch(); + rpc_teardown(base); + if (test_ok != 1) { fprintf(stdout, "FAILED\n"); exit(1); @@ -399,6 +410,8 @@ rpc_basic_client(void) event_dispatch(); + rpc_teardown(base); + if (test_ok != 2) { fprintf(stdout, "FAILED (2)\n"); exit(1); @@ -448,6 +461,8 @@ rpc_basic_queued_client(void) event_dispatch(); + rpc_teardown(base); + if (test_ok != 2) { fprintf(stdout, "FAILED (1)\n"); exit(1); @@ -508,6 +523,8 @@ rpc_client_timeout(void) event_dispatch(); + rpc_teardown(base); + if (test_ok != 2) { fprintf(stdout, "FAILED (1)\n"); exit(1);