libevent
|
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_ */