#include <sys/ioctl.h>
#endif
+#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
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))
va_end(aq);
- if (sz == -1)
+ if (sz < 0)
return (-1);
if (sz < space) {
buf->off += sz;
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 *);
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)
{
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
*/
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)
*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)
{
test_ok = 0;
event_dispatch();
+
+ rpc_teardown(base);
if (test_ok != 1) {
fprintf(stdout, "FAILED\n");
event_dispatch();
+ rpc_teardown(base);
+
if (test_ok != 1) {
fprintf(stdout, "FAILED\n");
exit(1);
event_dispatch();
+ rpc_teardown(base);
+
if (test_ok != 2) {
fprintf(stdout, "FAILED (2)\n");
exit(1);
event_dispatch();
+ rpc_teardown(base);
+
if (test_ok != 2) {
fprintf(stdout, "FAILED (1)\n");
exit(1);
event_dispatch();
+ rpc_teardown(base);
+
if (test_ok != 2) {
fprintf(stdout, "FAILED (1)\n");
exit(1);