]> granicus.if.org Git - libevent/commitdiff
move more code directly into evrpc.c; provide backwards compatible vararg macros
authorNiels Provos <provos@gmail.com>
Sat, 25 Apr 2009 00:15:55 +0000 (00:15 +0000)
committerNiels Provos <provos@gmail.com>
Sat, 25 Apr 2009 00:15:55 +0000 (00:15 +0000)
svn:r1244

Doxyfile
evrpc.c
evrpc.h
include/Makefile.am
include/event2/rpc.h
include/event2/rpc_compat.h [new file with mode: 0644]
include/event2/rpc_struct.h

index 62b83efa7870ce51c48742f46301f2d4df9dfe4e..3fc853e5db1910f1a8b12f13ea0e3177d1f7c29b 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -64,6 +64,7 @@ INPUT                  = event.h evdns.h evhttp.h evrpc.h \
                       include/event2/bufferevent_compat.h \
                       include/event2/util.h \
                       include/event2/rpc.h include/event2/rpc_struct.h \
+                      include/event2/rpc_compat.h \
                       include/event2/dns.h include/event2/dns_struct.h \
                       include/event2/dns_compat.h \
                       include/event2/http.h include/event2/http_struct.h \
diff --git a/evrpc.c b/evrpc.c
index c1d7ebf95960b2b506ba1ba0aa96fc1faa545609..1de50ca6a8f868d420a5b03cc3505839889ec7f0 100644 (file)
--- a/evrpc.c
+++ b/evrpc.c
@@ -1042,6 +1042,76 @@ evrpc_hook_get_connection(void *ctx)
        return (req->hook_meta != NULL ? req->hook_meta->evcon : NULL);
 }
 
+int
+evrpc_send_request_generic(struct evrpc_pool *pool,
+    void *request, void *reply,
+    void (*cb)(struct evrpc_status *, void *, void *, void *),
+    void *cb_arg,
+    const char *rpcname,
+    void (*req_marshal)(struct evbuffer *, void *),
+    void (*rpl_clear)(void *),
+    int (*rpl_unmarshal)(void *, struct evbuffer *))
+{
+       struct evrpc_status status;
+       struct evrpc_request_wrapper *ctx;
+       ctx = evrpc_make_request_ctx(pool, request, reply,
+           rpcname, req_marshal, rpl_clear, rpl_unmarshal, cb, cb_arg);
+       if (ctx == NULL)
+               goto error;
+       return (evrpc_make_request(ctx));
+error:
+       memset(&status, 0, sizeof(status));
+       status.error = EVRPC_STATUS_ERR_UNSTARTED;
+       (*(cb))(&status, request, reply, cb_arg);
+       return (-1);
+}
+
+/** 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 *),
+    int (*req_unmarshal)(void *, struct evbuffer *),
+    void *(*rpl_new)(void), void (*rpl_free)(void *),
+    int (*rpl_complete)(void *),
+    void (*rpl_marshal)(struct evbuffer *, void *))
+{
+       struct evrpc* rpc = (struct evrpc *)mm_calloc(1, sizeof(struct evrpc));
+       if (rpc == NULL)
+               return (NULL);
+       rpc->uri = mm_strdup(name);
+       if (rpc->uri == NULL) {
+               mm_free(rpc);
+               return (NULL);
+       }
+       rpc->request_new = req_new;
+       rpc->request_free = req_free;
+       rpc->request_unmarshal = req_unmarshal;
+       rpc->reply_new = rpl_new;
+       rpc->reply_free = rpl_free;
+       rpc->reply_complete = rpl_complete;
+       rpc->reply_marshal = rpl_marshal;
+       return (rpc);
+}
+
+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 *),
+    int (*req_unmarshal)(void *, struct evbuffer *),
+    void *(*rpl_new)(void), 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);
+       if (rpc == NULL)
+               return (-1);
+       evrpc_register_rpc(base, rpc,
+           (void (*)(struct evrpc_req_generic*, void *))callback, cbarg);
+       return (0);
+}
+
 /** accessors for obscure and undocumented functionality */
 struct evrpc_pool *
 evrpc_request_get_pool(struct evrpc_request_wrapper *ctx)
diff --git a/evrpc.h b/evrpc.h
index 0e88806ae6bd85a2c326da7e2578882e2d3575a1..a7e27a9053c444f9cfa31f4761526c81371bf36a 100644 (file)
--- a/evrpc.h
+++ b/evrpc.h
@@ -30,5 +30,6 @@
 #include <event.h>
 #include <event2/rpc.h>
 #include <event2/rpc_struct.h>
+#include <event2/rpc_compat.h>
 
 #endif /* _EVRPC_H_ */
index 4be3a730c0d525f6d7a385af17a1f0ff7e136184..6a80feb6c940e3d709ea1f174ec9d350953473ad 100644 (file)
@@ -15,5 +15,5 @@ nobase_include_HEADERS = \
         event2/bufferevent_struct.h event2/event.h event2/event_compat.h \
         event2/event_struct.h event2/tag.h event2/util.h \
        event2/http.h event2/http_struct.h event2/http_compat.h \
-       event2/rpc.h event2/rpc_struct.h \
+       event2/rpc.h event2/rpc_struct.h event2/rpc_compat.h \
        event2/dns.h event2/dns_struct.h event2/dns_compat.h
index 3d70f08fbb4255de97224ad1a77819d46a4b04d2..dfa7966b64a87653426091f22cc473b3c946e0f0 100644 (file)
@@ -76,6 +76,8 @@ extern "C" {
 #define EVTAG_HAS(msg, member) \
        ((msg)->member##_set == 1)
 
+#ifndef _EVENT2_RPC_COMPAT_H_
+
 /**
    Assigns a value to the member in the message.
 
@@ -117,6 +119,8 @@ extern "C" {
 #define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen)  \
        (*(msg)->base->member##_get)(msg, pvalue, plen)
 
+#endif  /* _EVENT2_RPC_COMPAT_H_ */
+
 /**
    Adds a value to an array.
 */
@@ -137,6 +141,8 @@ extern "C" {
 */
 #define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length)
 
+
+
 struct evbuffer;
 struct event_base;
 struct evrpc_req_generic;
@@ -225,31 +231,21 @@ struct evrpc_request_wrapper *evrpc_make_request_ctx(
  * @param replystruct the name of the RPC reply structure
  * @see EVRPC_HEADER()
  */
-#define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \
-int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \
-    struct reqstruct *request, struct rplystruct *reply, \
-    void (*cb)(struct evrpc_status *, \
-       struct reqstruct *, struct rplystruct *, void *cbarg),  \
-    void *cbarg) { \
-       struct evrpc_status status;                                 \
-       struct evrpc_request_wrapper *ctx;                          \
-       ctx = evrpc_make_request_ctx(pool, request, reply,          \
-           #rpcname,                                               \
-           (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \
-           (void (*)(void *))rplystruct##_clear, \
-           (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \
+#define EVRPC_GENERATE(rpcname, reqstruct, rplystruct)                 \
+       int evrpc_send_request_##rpcname(struct evrpc_pool *pool,       \
+           struct reqstruct *request, struct rplystruct *reply,        \
+           void (*cb)(struct evrpc_status *,                           \
+               struct reqstruct *, struct rplystruct *, void *cbarg),  \
+           void *cbarg) {                                              \
+       return evrpc_send_request_generic(pool, request, reply, \
            (void (*)(struct evrpc_status *, void *, void *, void *))cb, \
-           cbarg);                                                     \
-       if (ctx == NULL)                                            \
-               goto error;                                         \
-       return (evrpc_make_request(ctx));                           \
-error:                                                             \
-       memset(&status, 0, sizeof(status));                         \
-       status.error = EVRPC_STATUS_ERR_UNSTARTED;                  \
-       (*(cb))(&status, request, reply, cbarg);                    \
-       return (-1);                                                \
+           cbarg,                                                      \
+           #rpcname,                                                   \
+           (void (*)(struct evbuffer *, void *))reqstruct##_marshal,   \
+           (void (*)(void *))rplystruct##_clear,                       \
+           (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \
 }
-
+       
 /** Provides access to the HTTP request object underlying an RPC
  *
  * Access to the underlying http object; can be used to look at headers or
@@ -278,23 +274,6 @@ void evrpc_request_done(struct evrpc_req_generic *req);
 } while (0)
   
 
-/* Takes a request object and fills it in with the right magic */
-#define EVRPC_REGISTER_OBJECT(rpc, name, request, reply) \
-  do { \
-    (rpc)->uri = strdup(#name); \
-    if ((rpc)->uri == NULL) {                   \
-      fprintf(stderr, "failed to register object\n");  \
-      exit(1);                                         \
-    } \
-    (rpc)->request_new = (void *(*)(void))request##_new; \
-    (rpc)->request_free = (void (*)(void *))request##_free; \
-    (rpc)->request_unmarshal = (int (*)(void *, struct evbuffer *))request##_unmarshal; \
-    (rpc)->reply_new = (void *(*)(void))reply##_new; \
-    (rpc)->reply_free = (void (*)(void *))reply##_free; \
-    (rpc)->reply_complete = (int (*)(void *))reply##_complete; \
-    (rpc)->reply_marshal = (void (*)(struct evbuffer*, void *))reply##_marshal; \
-  } while (0)
-
 struct evrpc_base;
 struct evhttp;
 
@@ -334,14 +313,24 @@ void evrpc_free(struct evrpc_base *base);
  * @param cbarg an additional parameter that can be passed to the callback.
  *   The parameter can be used to carry around state.
  */
-#define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \
-  do { \
-    struct evrpc* rpc = (struct evrpc *)calloc(1, sizeof(struct evrpc)); \
-    EVRPC_REGISTER_OBJECT(rpc, name, request, reply); \
-    evrpc_register_rpc(base, rpc, \
-       (void (*)(struct evrpc_req_generic*, void *))callback, cbarg);  \
-  } while (0)
+#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##_free,                           \
+           (int (*)(void *, struct evbuffer *))request##_unmarshal,    \
+           (void *(*)(void))reply##_new, \
+           (void (*)(void *))reply##_free, \
+           (int (*)(void *))reply##_complete, \
+           (void (*)(struct evbuffer *, void *))reply##_marshal)
+
+/**
+   Low level function for registering an RPC with a server.
+
+   Use EVRPC_REGISTER() instead.
 
+   @see EVRPC_REGISTER()
+*/
 int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
     void (*)(struct evrpc_req_generic*, void *), void *);
 
@@ -362,21 +351,7 @@ int evrpc_unregister_rpc(struct evrpc_base *base, const char *name);
  */
 
 struct evhttp_connection;
-
-/** 
- * provides information about the completed RPC request.
- */
-struct evrpc_status {
-#define EVRPC_STATUS_ERR_NONE          0
-#define EVRPC_STATUS_ERR_TIMEOUT       1
-#define EVRPC_STATUS_ERR_BADPAYLOAD    2
-#define EVRPC_STATUS_ERR_UNSTARTED     3
-#define EVRPC_STATUS_ERR_HOOKABORTED   4
-       int error;
-
-       /* for looking at headers or other information */
-       struct evhttp_request *http_req;
-};
+struct evrpc_status;
 
 /** launches an RPC and sends it to the server
  *
@@ -396,7 +371,18 @@ struct evrpc_status {
 #define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg)      \
        evrpc_send_request_##name(pool, request, reply, cb, cbarg)
 
-int evrpc_make_request(struct evrpc_request_wrapper *);
+/**
+   Makes an RPC request based on the provided context.
+
+   This is a low-level function and should not be used directly
+   unless a custom context object is provided.  Use EVRPC_MAKE_REQUEST()
+   instead.
+
+   @param ctx a context from EVRPC_MAKE_CTX()
+   @returns 0 on success, -1 otherwise.
+   @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX()
+*/
+int evrpc_make_request(struct evrpc_request_wrapper *ctx);
 
 /** creates an rpc connection pool
  * 
@@ -552,13 +538,46 @@ void evrpc_hook_add_meta(void *ctx, const char *key,
 int evrpc_hook_find_meta(void *ctx, const char *key,
     void **data, size_t *data_size);
 
-/** returns the connection object associated with the request
+/** 
+ * returns the connection object associated with the request
  *
  * @param ctx the context provided to the hook call
  * @return a pointer to the evhttp_connection object
  */
 struct evhttp_connection *evrpc_hook_get_connection(void *ctx);
 
+/**
+   Function for sending a generic RPC request.
+
+   Do not call this function directly, use EVRPC_MAKE_REQUEST() instead.
+
+   @see EVRPC_MAKE_REQUEST()
+ */
+int evrpc_send_request_generic(struct evrpc_pool *pool,
+    void *request, void *reply,
+    void (*cb)(struct evrpc_status *, void *, void *, void *),
+    void *cb_arg,
+    const char *rpcname,
+    void (*req_marshal)(struct evbuffer *, void *),
+    void (*rpl_clear)(void *),
+    int (*rpl_unmarshal)(void *, struct evbuffer *));
+
+/**
+   Function for registering a generic RPC with the RPC base.
+    
+   Do not call this function directly, use EVRPC_REGISTER() instead.
+
+   @see EVRPC_REGISTER()
+ */
+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 *),
+    int (*req_unmarshal)(void *, struct evbuffer *),
+    void *(*rpl_new)(void), void (*rpl_free)(void *),
+    int (*rpl_complete)(void *),
+    void (*rpl_marshal)(struct evbuffer *, void *));
+
 /** accessors for obscure and undocumented functionality */
 struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx);
 void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx,
diff --git a/include/event2/rpc_compat.h b/include/event2/rpc_compat.h
new file mode 100644 (file)
index 0000000..5711efa
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu>
+ * Copyright (c) 2007-2009 Niels Provos and Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _EVENT2_RPC_COMPAT_H_
+#define _EVENT2_RPC_COMPAT_H_
+
+/** @file rpc_compat.h
+
+  Deprecated versions of the functions in rpc.h: provided only for
+  backwards compatibility.
+
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** backwards compatible accessors that work only with gcc */
+#ifdef __GNUC__
+
+#undef EVTAG_ASSIGN
+#undef EVTAG_GET
+#undef EVTAG_ADD
+
+#define EVTAG_ASSIGN(msg, member, args...) \
+       (*(msg)->base->member##_assign)(msg, ## args)
+#define EVTAG_GET(msg, member, args...) \
+       (*(msg)->base->member##_get)(msg, ## args)
+#define EVTAG_ADD(msg, member, args...) \
+       (*(msg)->base->member##_add)(msg, ## args)
+#endif
+#define EVTAG_LEN(msg, member) ((msg)->member##_length)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EVENT2_EVENT_COMPAT_H_ */
index d7d3f46fe585224055510a228989e103e02cff4e..51d0e765bd128d24c688c5cad0d0d252eb08133b 100644 (file)
@@ -32,10 +32,27 @@ extern "C" {
 #endif
 
 /** @file rpc_struct.h
- *
- * This header files provides basic support for an RPC server and client.
+
+  Structures used by rpc.h.  Using these structures directly may harm
+  forward compatibility: be careful!
+
  */
 
+/** 
+ * provides information about the completed RPC request.
+ */
+struct evrpc_status {
+#define EVRPC_STATUS_ERR_NONE          0
+#define EVRPC_STATUS_ERR_TIMEOUT       1
+#define EVRPC_STATUS_ERR_BADPAYLOAD    2
+#define EVRPC_STATUS_ERR_UNSTARTED     3
+#define EVRPC_STATUS_ERR_HOOKABORTED   4
+       int error;
+
+       /* for looking at headers or other information */
+       struct evhttp_request *http_req;
+};
+
 /* the structure below needs to be synchronized with evrpc_req_generic */
 
 /* Encapsulates a request */