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)
This commit is contained in:
Shuo Chen 2010-04-14 14:27:29 -04:00 committed by Nick Mathewson
parent 07edf784fa
commit 755fbf16c3
4 changed files with 26 additions and 15 deletions

View File

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

18
evrpc.c
View File

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

View File

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

View File

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