libevent

include/event2/rpc.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu>
00003  * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. The name of the author may not be used to endorse or promote products
00014  *    derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00018  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00019  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00020  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00021  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00025  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 #ifndef _EVENT2_RPC_H_
00028 #define _EVENT2_RPC_H_
00029 
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033 
00076 #define EVTAG_HAS(msg, member) \
00077         ((msg)->member##_set == 1)
00078 
00079 #ifndef _EVENT2_RPC_COMPAT_H_
00080 
00088 #define EVTAG_ASSIGN(msg, member, value) \
00089         (*(msg)->base->member##_assign)((msg), (value))
00090 
00098 #define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len)  \
00099         (*(msg)->base->member##_assign)((msg), (value), (len))
00100 
00108 #define EVTAG_GET(msg, member, pvalue) \
00109         (*(msg)->base->member##_get)((msg), (pvalue))
00110 
00119 #define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen)   \
00120         (*(msg)->base->member##_get)((msg), (pvalue), (plen))
00121 
00122 #endif  /* _EVENT2_RPC_COMPAT_H_ */
00123 
00127 #define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \
00128         (*(msg)->base->member##_add)((msg), (value))
00129 
00132 #define EVTAG_ARRAY_ADD(msg, member) \
00133         (*(msg)->base->member##_add)(msg)
00134 
00137 #define EVTAG_ARRAY_GET(msg, member, offset, pvalue)    \
00138         (*(msg)->base->member##_get)((msg), (offset), (pvalue))
00139 
00142 #define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length)
00143 
00144 
00145 struct evbuffer;
00146 struct event_base;
00147 struct evrpc_req_generic;
00148 struct evrpc_request_wrapper;
00149 struct evrpc;
00150 
00155 #define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname
00156 
00157 struct evhttp_request;
00158 struct evrpc_status;
00159 struct evrpc_hook_meta;
00160 
00172 #define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \
00173 EVRPC_STRUCT(rpcname) { \
00174         struct evrpc_hook_meta *hook_meta; \
00175         struct reqstruct* request; \
00176         struct rplystruct* reply; \
00177         struct evrpc* rpc; \
00178         struct evhttp_request* http_req; \
00179         struct evbuffer* rpc_data; \
00180 };                                                                   \
00181 int evrpc_send_request_##rpcname(struct evrpc_pool *, \
00182     struct reqstruct *, struct rplystruct *, \
00183     void (*)(struct evrpc_status *, \
00184         struct reqstruct *, struct rplystruct *, void *cbarg),  \
00185     void *);
00186 
00187 struct evrpc_pool;
00188 
00190 struct evrpc_request_wrapper *evrpc_make_request_ctx(
00191         struct evrpc_pool *pool, void *request, void *reply,
00192         const char *rpcname,
00193         void (*req_marshal)(struct evbuffer*, void *),
00194         void (*rpl_clear)(void *),
00195         int (*rpl_unmarshal)(void *, struct evbuffer *),
00196         void (*cb)(struct evrpc_status *, void *, void *, void *),
00197         void *cbarg);
00198 
00213 #define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \
00214     pool, request, reply, cb, cbarg)                                    \
00215         evrpc_make_request_ctx(pool, request, reply,                    \
00216             #rpcname,                                                   \
00217             (void (*)(struct evbuffer *, void *))reqstruct##_marshal,   \
00218             (void (*)(void *))rplystruct##_clear,                       \
00219             (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \
00220             (void (*)(struct evrpc_status *, void *, void *, void *))cb, \
00221             cbarg)
00222 
00233 #define EVRPC_GENERATE(rpcname, reqstruct, rplystruct)                  \
00234         int evrpc_send_request_##rpcname(struct evrpc_pool *pool,       \
00235             struct reqstruct *request, struct rplystruct *reply,        \
00236             void (*cb)(struct evrpc_status *,                           \
00237                 struct reqstruct *, struct rplystruct *, void *cbarg),  \
00238             void *cbarg) {                                              \
00239         return evrpc_send_request_generic(pool, request, reply, \
00240             (void (*)(struct evrpc_status *, void *, void *, void *))cb, \
00241             cbarg,                                                      \
00242             #rpcname,                                                   \
00243             (void (*)(struct evbuffer *, void *))reqstruct##_marshal,   \
00244             (void (*)(void *))rplystruct##_clear,                       \
00245             (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \
00246 }
00247 
00257 #define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req
00258 
00260 void evrpc_request_done(struct evrpc_req_generic *req);
00261 
00263 void *evrpc_get_request(struct evrpc_req_generic *req);
00264 void *evrpc_get_reply(struct evrpc_req_generic *req);
00265 
00274 #define EVRPC_REQUEST_DONE(rpc_req) do { \
00275   struct evrpc_req_generic *_req = (struct evrpc_req_generic *)(rpc_req); \
00276   evrpc_request_done(_req);                                     \
00277 } while (0)
00278 
00279 
00280 struct evrpc_base;
00281 struct evhttp;
00282 
00283 /* functions to start up the rpc system */
00284 
00291 struct evrpc_base *evrpc_init(struct evhttp *server);
00292 
00301 void evrpc_free(struct evrpc_base *base);
00302 
00319 #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg)     \
00320         evrpc_register_generic(base, #name,                             \
00321             (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \
00322             (void *(*)(void *))request##_new, NULL,                     \
00323             (void (*)(void *))request##_free,                           \
00324             (int (*)(void *, struct evbuffer *))request##_unmarshal,    \
00325             (void *(*)(void *))reply##_new, NULL,                       \
00326             (void (*)(void *))reply##_free, \
00327             (int (*)(void *))reply##_complete, \
00328             (void (*)(struct evbuffer *, void *))reply##_marshal)
00329 
00337 int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
00338     void (*)(struct evrpc_req_generic*, void *), void *);
00339 
00348 #define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name)
00349 
00350 int evrpc_unregister_rpc(struct evrpc_base *base, const char *name);
00351 
00352 /*
00353  * Client-side RPC support
00354  */
00355 
00356 struct evhttp_connection;
00357 struct evrpc_status;
00358 
00374 #define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg)       \
00375         evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg))
00376 
00388 int evrpc_make_request(struct evrpc_request_wrapper *ctx);
00389 
00400 struct evrpc_pool *evrpc_pool_new(struct event_base *base);
00406 void evrpc_pool_free(struct evrpc_pool *pool);
00407 
00416 void evrpc_pool_add_connection(struct evrpc_pool *pool,
00417     struct evhttp_connection *evcon);
00418 
00427 void evrpc_pool_remove_connection(struct evrpc_pool *pool,
00428     struct evhttp_connection *evcon);
00429 
00445 void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs);
00446 
00452 enum EVRPC_HOOK_TYPE {
00453         EVRPC_INPUT,            
00454         EVRPC_OUTPUT            
00455 };
00456 
00457 #ifndef WIN32
00458 
00460 #define INPUT EVRPC_INPUT
00461 
00463 #define OUTPUT EVRPC_OUTPUT
00464 #endif
00465 
00470 enum EVRPC_HOOK_RESULT {
00471         EVRPC_TERMINATE = -1,   
00472         EVRPC_CONTINUE = 0,     
00473         EVRPC_PAUSE = 1         
00474 };
00475 
00492 void *evrpc_add_hook(void *vbase,
00493     enum EVRPC_HOOK_TYPE hook_type,
00494     int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *),
00495     void *cb_arg);
00496 
00505 int evrpc_remove_hook(void *vbase,
00506     enum EVRPC_HOOK_TYPE hook_type,
00507     void *handle);
00508 
00514 int
00515 evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res);
00516 
00528 void evrpc_hook_add_meta(void *ctx, const char *key,
00529     const void *data, size_t data_size);
00530 
00541 int evrpc_hook_find_meta(void *ctx, const char *key,
00542     void **data, size_t *data_size);
00543 
00550 struct evhttp_connection *evrpc_hook_get_connection(void *ctx);
00551 
00559 int evrpc_send_request_generic(struct evrpc_pool *pool,
00560     void *request, void *reply,
00561     void (*cb)(struct evrpc_status *, void *, void *, void *),
00562     void *cb_arg,
00563     const char *rpcname,
00564     void (*req_marshal)(struct evbuffer *, void *),
00565     void (*rpl_clear)(void *),
00566     int (*rpl_unmarshal)(void *, struct evbuffer *));
00567 
00575 int
00576 evrpc_register_generic(struct evrpc_base *base, const char *name,
00577     void (*callback)(struct evrpc_req_generic *, void *), void *cbarg,
00578     void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *),
00579     int (*req_unmarshal)(void *, struct evbuffer *),
00580     void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *),
00581     int (*rpl_complete)(void *),
00582     void (*rpl_marshal)(struct evbuffer *, void *));
00583 
00585 struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx);
00586 void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx,
00587     struct evrpc_pool *pool);
00588 void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx,
00589     void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg),
00590     void *cb_arg);
00591 
00592 #ifdef __cplusplus
00593 }
00594 #endif
00595 
00596 #endif /* _EVENT2_RPC_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines