From 755fbf16c3ce94bfa09e1bf5da27ccdfc1e7e725 Mon Sep 17 00:00:00 2001 From: Shuo Chen Date: Wed, 14 Apr 2010 14:27:29 -0400 Subject: [PATCH] Add void* arguments to request_new and reply_new evrpc hooks This makes evprc setup more extensible, and helps with Shuo Chen's work on implementing Google protocol buffers rpc on top of Libevent 2 evrpc. This patch breaks binary compatibility with previous versions of Libevent, since it changes struct evrpc and the signature of evrpc_register_generic(). Since all compliant code should be calling evrpc_register_generic via EVRPC_REGISTER, it shouldn't break source compatibility. (Code by Shuo Chen; commit message by Nick) --- event_rpcgen.py | 7 +++++++ evrpc.c | 18 ++++++++++-------- include/event2/rpc.h | 8 ++++---- include/event2/rpc_struct.h | 8 +++++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/event_rpcgen.py b/event_rpcgen.py index f8d14d62..9eb75762 100755 --- a/event_rpcgen.py +++ b/event_rpcgen.py @@ -117,6 +117,7 @@ class StructCCode(Struct): print >>file, \ """struct %(name)s *%(name)s_new(void); +struct %(name)s *%(name)s_new_with_arg(void *); void %(name)s_free(struct %(name)s *); void %(name)s_clear(struct %(name)s *); void %(name)s_marshal(struct evbuffer *, const struct %(name)s *); @@ -157,6 +158,12 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, 'struct %(name)s *\n' '%(name)s_new(void)\n' '{\n' + ' return %(name)s_new_with_arg(NULL);\n' + '}\n' + '\n' + 'struct %(name)s *\n' + '%(name)s_new_with_arg(void *unused)\n' + '{\n' ' struct %(name)s *tmp;\n' ' if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n' ' event_warn("%%s: malloc", __func__);\n' diff --git a/evrpc.c b/evrpc.c index b5e4ca8c..ba72e24d 100644 --- a/evrpc.c +++ b/evrpc.c @@ -339,7 +339,7 @@ evrpc_request_cb_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res) goto error; /* let's check that we can parse the request */ - rpc_state->request = rpc->request_new(); + rpc_state->request = rpc->request_new(rpc->request_new_arg); if (rpc_state->request == NULL) goto error; @@ -351,7 +351,7 @@ evrpc_request_cb_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res) /* at this point, we have a well formed request, prepare the reply */ - rpc_state->reply = rpc->reply_new(); + rpc_state->reply = rpc->reply_new(rpc->reply_new_arg); if (rpc_state->reply == NULL) goto error; @@ -1081,9 +1081,9 @@ error: /** Takes a request object and fills it in with the right magic */ static struct evrpc * evrpc_register_object(const char *name, - void *(*req_new)(void), void (*req_free)(void *), + void *(*req_new)(void*), void *req_new_arg, void (*req_free)(void *), int (*req_unmarshal)(void *, struct evbuffer *), - void *(*rpl_new)(void), void (*rpl_free)(void *), + void *(*rpl_new)(void*), void *rpl_new_arg, void (*rpl_free)(void *), int (*rpl_complete)(void *), void (*rpl_marshal)(struct evbuffer *, void *)) { @@ -1096,9 +1096,11 @@ evrpc_register_object(const char *name, return (NULL); } rpc->request_new = req_new; + rpc->request_new_arg = req_new_arg; rpc->request_free = req_free; rpc->request_unmarshal = req_unmarshal; rpc->reply_new = rpl_new; + rpc->reply_new_arg = rpl_new_arg; rpc->reply_free = rpl_free; rpc->reply_complete = rpl_complete; rpc->reply_marshal = rpl_marshal; @@ -1108,15 +1110,15 @@ evrpc_register_object(const char *name, int evrpc_register_generic(struct evrpc_base *base, const char *name, void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, - void *(*req_new)(void), void (*req_free)(void *), + void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), int (*req_unmarshal)(void *, struct evbuffer *), - void *(*rpl_new)(void), void (*rpl_free)(void *), + void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), int (*rpl_complete)(void *), void (*rpl_marshal)(struct evbuffer *, void *)) { struct evrpc* rpc = - evrpc_register_object(name, req_new, req_free, req_unmarshal, - rpl_new, rpl_free, rpl_complete, rpl_marshal); + evrpc_register_object(name, req_new, req_new_arg, req_free, req_unmarshal, + rpl_new, rpl_new_arg, rpl_free, rpl_complete, rpl_marshal); if (rpc == NULL) return (-1); evrpc_register_rpc(base, rpc, diff --git a/include/event2/rpc.h b/include/event2/rpc.h index c11e77ca..66a2612e 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -319,10 +319,10 @@ void evrpc_free(struct evrpc_base *base); #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ evrpc_register_generic(base, #name, \ (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ - (void *(*)(void))request##_new, \ + (void *(*)(void *))request##_new, NULL, \ (void (*)(void *))request##_free, \ (int (*)(void *, struct evbuffer *))request##_unmarshal, \ - (void *(*)(void))reply##_new, \ + (void *(*)(void *))reply##_new, NULL, \ (void (*)(void *))reply##_free, \ (int (*)(void *))reply##_complete, \ (void (*)(struct evbuffer *, void *))reply##_marshal) @@ -575,9 +575,9 @@ int evrpc_send_request_generic(struct evrpc_pool *pool, int evrpc_register_generic(struct evrpc_base *base, const char *name, void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, - void *(*req_new)(void), void (*req_free)(void *), + void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), int (*req_unmarshal)(void *, struct evbuffer *), - void *(*rpl_new)(void), void (*rpl_free)(void *), + void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), int (*rpl_complete)(void *), void (*rpl_marshal)(struct evbuffer *, void *)); diff --git a/include/event2/rpc_struct.h b/include/event2/rpc_struct.h index bd23fd37..c1efe1d8 100644 --- a/include/event2/rpc_struct.h +++ b/include/event2/rpc_struct.h @@ -63,7 +63,8 @@ struct evrpc { const char* uri; /* creates a new request structure */ - void *(*request_new)(void); + void *(*request_new)(void *); + void *request_new_arg; /* frees the request structure */ void (*request_free)(void *); @@ -72,9 +73,10 @@ struct evrpc { int (*request_unmarshal)(void *, struct evbuffer *); /* creates a new reply structure */ - void *(*reply_new)(void); + void *(*reply_new)(void *); + void *reply_new_arg; - /* creates a new reply structure */ + /* frees the reply structure */ void (*reply_free)(void *); /* verifies that the reply is valid */