support removing of http callbacks and removing of registered RPCs

svn:r355
This commit is contained in:
Niels Provos 2007-05-23 05:20:59 +00:00
parent 5b5400f66b
commit 0c2808246a
6 changed files with 80 additions and 2 deletions

View File

@ -44,6 +44,7 @@
#include <sys/ioctl.h>
#endif
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -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;

View File

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

29
evrpc.c
View File

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

View File

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

19
http.c
View File

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

View File

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