1 /* 2 * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu> 3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef EVENT2_RPC_H_INCLUDED_ 28 #define EVENT2_RPC_H_INCLUDED_ 29 30 /* For int types. */ 31 #include <event2/util.h> 32 #include <event2/visibility.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /** @file rpc.h 39 * 40 * This header files provides basic support for an RPC server and client. 41 * 42 * To support RPCs in a server, every supported RPC command needs to be 43 * defined and registered. 44 * 45 * EVRPC_HEADER(SendCommand, Request, Reply); 46 * 47 * SendCommand is the name of the RPC command. 48 * Request is the name of a structure generated by event_rpcgen.py. 49 * It contains all parameters relating to the SendCommand RPC. The 50 * server needs to fill in the Reply structure. 51 * Reply is the name of a structure generated by event_rpcgen.py. It 52 * contains the answer to the RPC. 53 * 54 * To register an RPC with an HTTP server, you need to first create an RPC 55 * base with: 56 * 57 * struct evrpc_base *base = evrpc_init(http); 58 * 59 * A specific RPC can then be registered with 60 * 61 * EVRPC_REGISTER(base, SendCommand, Request, Reply, FunctionCB, arg); 62 * 63 * when the server receives an appropriately formatted RPC, the user callback 64 * is invoked. The callback needs to fill in the reply structure. 65 * 66 * void FunctionCB(EVRPC_STRUCT(SendCommand)* rpc, void *arg); 67 * 68 * To send the reply, call EVRPC_REQUEST_DONE(rpc); 69 * 70 * See the regression test for an example. 71 */ 72 73 /** 74 Determines if the member has been set in the message 75 76 @param msg the message to inspect 77 @param member the member variable to test for presences 78 @return 1 if it's present or 0 otherwise. 79 */ 80 #define EVTAG_HAS(msg, member) \ 81 ((msg)->member##_set == 1) 82 83 #ifndef EVENT2_RPC_COMPAT_H_INCLUDED_ 84 85 /** 86 Assigns a value to the member in the message. 87 88 @param msg the message to which to assign a value 89 @param member the name of the member variable 90 @param value the value to assign 91 */ 92 #define EVTAG_ASSIGN(msg, member, value) \ 93 (*(msg)->base->member##_assign)((msg), (value)) 94 /** 95 Assigns a value to the member in the message. 96 97 @param msg the message to which to assign a value 98 @param member the name of the member variable 99 @param value the value to assign 100 @param len the length of the value 101 */ 102 #define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len) \ 103 (*(msg)->base->member##_assign)((msg), (value), (len)) 104 /** 105 Returns the value for a member. 106 107 @param msg the message from which to get the value 108 @param member the name of the member variable 109 @param pvalue a pointer to the variable to hold the value 110 @return 0 on success, -1 otherwise. 111 */ 112 #define EVTAG_GET(msg, member, pvalue) \ 113 (*(msg)->base->member##_get)((msg), (pvalue)) 114 /** 115 Returns the value for a member. 116 117 @param msg the message from which to get the value 118 @param member the name of the member variable 119 @param pvalue a pointer to the variable to hold the value 120 @param plen a pointer to the length of the value 121 @return 0 on success, -1 otherwise. 122 */ 123 #define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen) \ 124 (*(msg)->base->member##_get)((msg), (pvalue), (plen)) 125 126 #endif /* EVENT2_RPC_COMPAT_H_INCLUDED_ */ 127 128 /** 129 Adds a value to an array. 130 */ 131 #define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \ 132 (*(msg)->base->member##_add)((msg), (value)) 133 /** 134 Allocates a new entry in the array and returns it. 135 */ 136 #define EVTAG_ARRAY_ADD(msg, member) \ 137 (*(msg)->base->member##_add)(msg) 138 /** 139 Gets a variable at the specified offset from the array. 140 */ 141 #define EVTAG_ARRAY_GET(msg, member, offset, pvalue) \ 142 (*(msg)->base->member##_get)((msg), (offset), (pvalue)) 143 /** 144 Returns the number of entries in the array. 145 */ 146 #define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length) 147 148 149 struct evbuffer; 150 struct event_base; 151 struct evrpc_req_generic; 152 struct evrpc_request_wrapper; 153 struct evrpc; 154 155 /** The type of a specific RPC Message 156 * 157 * @param rpcname the name of the RPC message 158 */ 159 #define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname 160 161 struct evhttp_request; 162 struct evrpc_status; 163 struct evrpc_hook_meta; 164 165 /** Creates the definitions and prototypes for an RPC 166 * 167 * You need to use EVRPC_HEADER to create structures and function prototypes 168 * needed by the server and client implementation. The structures have to be 169 * defined in an .rpc file and converted to source code via event_rpcgen.py 170 * 171 * @param rpcname the name of the RPC 172 * @param reqstruct the name of the RPC request structure 173 * @param replystruct the name of the RPC reply structure 174 * @see EVRPC_GENERATE() 175 */ 176 #define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \ 177 EVRPC_STRUCT(rpcname) { \ 178 struct evrpc_hook_meta *hook_meta; \ 179 struct reqstruct* request; \ 180 struct rplystruct* reply; \ 181 struct evrpc* rpc; \ 182 struct evhttp_request* http_req; \ 183 struct evbuffer* rpc_data; \ 184 }; \ 185 EVENT2_EXPORT_SYMBOL \ 186 int evrpc_send_request_##rpcname(struct evrpc_pool *, \ 187 struct reqstruct *, struct rplystruct *, \ 188 void (*)(struct evrpc_status *, \ 189 struct reqstruct *, struct rplystruct *, void *cbarg), \ 190 void *); 191 192 struct evrpc_pool; 193 194 /** use EVRPC_GENERATE instead */ 195 EVENT2_EXPORT_SYMBOL 196 struct evrpc_request_wrapper *evrpc_make_request_ctx( 197 struct evrpc_pool *pool, void *request, void *reply, 198 const char *rpcname, 199 void (*req_marshal)(struct evbuffer*, void *), 200 void (*rpl_clear)(void *), 201 int (*rpl_unmarshal)(void *, struct evbuffer *), 202 void (*cb)(struct evrpc_status *, void *, void *, void *), 203 void *cbarg); 204 205 /** Creates a context structure that contains rpc specific information. 206 * 207 * EVRPC_MAKE_CTX is used to populate a RPC specific context that 208 * contains information about marshaling the RPC data types. 209 * 210 * @param rpcname the name of the RPC 211 * @param reqstruct the name of the RPC request structure 212 * @param replystruct the name of the RPC reply structure 213 * @param pool the evrpc_pool over which to make the request 214 * @param request a pointer to the RPC request structure object 215 * @param reply a pointer to the RPC reply structure object 216 * @param cb the callback function to call when the RPC has completed 217 * @param cbarg the argument to supply to the callback 218 */ 219 #define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \ 220 pool, request, reply, cb, cbarg) \ 221 evrpc_make_request_ctx(pool, request, reply, \ 222 #rpcname, \ 223 (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 224 (void (*)(void *))rplystruct##_clear, \ 225 (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \ 226 (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 227 cbarg) 228 229 /** Generates the code for receiving and sending an RPC message 230 * 231 * EVRPC_GENERATE is used to create the code corresponding to sending 232 * and receiving a particular RPC message 233 * 234 * @param rpcname the name of the RPC 235 * @param reqstruct the name of the RPC request structure 236 * @param replystruct the name of the RPC reply structure 237 * @see EVRPC_HEADER() 238 */ 239 #define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \ 240 int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \ 241 struct reqstruct *request, struct rplystruct *reply, \ 242 void (*cb)(struct evrpc_status *, \ 243 struct reqstruct *, struct rplystruct *, void *cbarg), \ 244 void *cbarg) { \ 245 return evrpc_send_request_generic(pool, request, reply, \ 246 (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 247 cbarg, \ 248 #rpcname, \ 249 (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 250 (void (*)(void *))rplystruct##_clear, \ 251 (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \ 252 } 253 254 /** Provides access to the HTTP request object underlying an RPC 255 * 256 * Access to the underlying http object; can be used to look at headers or 257 * for getting the remote ip address 258 * 259 * @param rpc_req the rpc request structure provided to the server callback 260 * @return an struct evhttp_request object that can be inspected for 261 * HTTP headers or sender information. 262 */ 263 #define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req 264 265 /** completes the server response to an rpc request */ 266 EVENT2_EXPORT_SYMBOL 267 void evrpc_request_done(struct evrpc_req_generic *req); 268 269 /** accessors for request and reply */ 270 EVENT2_EXPORT_SYMBOL 271 void *evrpc_get_request(struct evrpc_req_generic *req); 272 EVENT2_EXPORT_SYMBOL 273 void *evrpc_get_reply(struct evrpc_req_generic *req); 274 275 /** Creates the reply to an RPC request 276 * 277 * EVRPC_REQUEST_DONE is used to answer a request; the reply is expected 278 * to have been filled in. The request and reply pointers become invalid 279 * after this call has finished. 280 * 281 * @param rpc_req the rpc request structure provided to the server callback 282 */ 283 #define EVRPC_REQUEST_DONE(rpc_req) do { \ 284 struct evrpc_req_generic *req_ = (struct evrpc_req_generic *)(rpc_req); \ 285 evrpc_request_done(req_); \ 286 } while (0) 287 288 289 struct evrpc_base; 290 struct evhttp; 291 292 /* functions to start up the rpc system */ 293 294 /** Creates a new rpc base from which RPC requests can be received 295 * 296 * @param server a pointer to an existing HTTP server 297 * @return a newly allocated evrpc_base struct or NULL if an error occurred 298 * @see evrpc_free() 299 */ 300 EVENT2_EXPORT_SYMBOL 301 struct evrpc_base *evrpc_init(struct evhttp *server); 302 303 /** 304 * Frees the evrpc base 305 * 306 * For now, you are responsible for making sure that no rpcs are ongoing. 307 * 308 * @param base the evrpc_base object to be freed 309 * @see evrpc_init 310 */ 311 EVENT2_EXPORT_SYMBOL 312 void evrpc_free(struct evrpc_base *base); 313 314 /** register RPCs with the HTTP Server 315 * 316 * registers a new RPC with the HTTP server, each RPC needs to have 317 * a unique name under which it can be identified. 318 * 319 * @param base the evrpc_base structure in which the RPC should be 320 * registered. 321 * @param name the name of the RPC 322 * @param request the name of the RPC request structure 323 * @param reply the name of the RPC reply structure 324 * @param callback the callback that should be invoked when the RPC 325 * is received. The callback has the following prototype 326 * void (*callback)(EVRPC_STRUCT(Message)* rpc, void *arg) 327 * @param cbarg an additional parameter that can be passed to the callback. 328 * The parameter can be used to carry around state. 329 */ 330 #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ 331 evrpc_register_generic(base, #name, \ 332 (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ 333 (void *(*)(void *))request##_new_with_arg, NULL, \ 334 (void (*)(void *))request##_free, \ 335 (int (*)(void *, struct evbuffer *))request##_unmarshal, \ 336 (void *(*)(void *))reply##_new_with_arg, NULL, \ 337 (void (*)(void *))reply##_free, \ 338 (int (*)(void *))reply##_complete, \ 339 (void (*)(struct evbuffer *, void *))reply##_marshal) 340 341 /** 342 Low level function for registering an RPC with a server. 343 344 Use EVRPC_REGISTER() instead. 345 346 @see EVRPC_REGISTER() 347 */ 348 EVENT2_EXPORT_SYMBOL 349 int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, 350 void (*)(struct evrpc_req_generic*, void *), void *); 351 352 /** 353 * Unregisters an already registered RPC 354 * 355 * @param base the evrpc_base object from which to unregister an RPC 356 * @param name the name of the rpc to unregister 357 * @return -1 on error or 0 when successful. 358 * @see EVRPC_REGISTER() 359 */ 360 #define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name) 361 362 EVENT2_EXPORT_SYMBOL 363 int evrpc_unregister_rpc(struct evrpc_base *base, const char *name); 364 365 /* 366 * Client-side RPC support 367 */ 368 369 struct evhttp_connection; 370 struct evrpc_status; 371 372 /** launches an RPC and sends it to the server 373 * 374 * EVRPC_MAKE_REQUEST() is used by the client to send an RPC to the server. 375 * 376 * @param name the name of the RPC 377 * @param pool the evrpc_pool that contains the connection objects over which 378 * the request should be sent. 379 * @param request a pointer to the RPC request structure - it contains the 380 * data to be sent to the server. 381 * @param reply a pointer to the RPC reply structure. It is going to be filled 382 * if the request was answered successfully 383 * @param cb the callback to invoke when the RPC request has been answered 384 * @param cbarg an additional argument to be passed to the client 385 * @return 0 on success, -1 on failure 386 */ 387 #define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg) \ 388 evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg)) 389 390 /** 391 Makes an RPC request based on the provided context. 392 393 This is a low-level function and should not be used directly 394 unless a custom context object is provided. Use EVRPC_MAKE_REQUEST() 395 instead. 396 397 @param ctx a context from EVRPC_MAKE_CTX() 398 @returns 0 on success, -1 otherwise. 399 @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX() 400 */ 401 EVENT2_EXPORT_SYMBOL 402 int evrpc_make_request(struct evrpc_request_wrapper *ctx); 403 404 /** creates an rpc connection pool 405 * 406 * a pool has a number of connections associated with it. 407 * rpc requests are always made via a pool. 408 * 409 * @param base a pointer to an struct event_based object; can be left NULL 410 * in singled-threaded applications 411 * @return a newly allocated struct evrpc_pool object or NULL if an error 412 * occurred 413 * @see evrpc_pool_free() 414 */ 415 EVENT2_EXPORT_SYMBOL 416 struct evrpc_pool *evrpc_pool_new(struct event_base *base); 417 /** frees an rpc connection pool 418 * 419 * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new() 420 * @see evrpc_pool_new() 421 */ 422 EVENT2_EXPORT_SYMBOL 423 void evrpc_pool_free(struct evrpc_pool *pool); 424 425 /** 426 * Adds a connection over which rpc can be dispatched to the pool. 427 * 428 * The connection object must have been newly created. 429 * 430 * @param pool the pool to which to add the connection 431 * @param evcon the connection to add to the pool. 432 */ 433 EVENT2_EXPORT_SYMBOL 434 void evrpc_pool_add_connection(struct evrpc_pool *pool, 435 struct evhttp_connection *evcon); 436 437 /** 438 * Removes a connection from the pool. 439 * 440 * The connection object must have been newly created. 441 * 442 * @param pool the pool from which to remove the connection 443 * @param evcon the connection to remove from the pool. 444 */ 445 EVENT2_EXPORT_SYMBOL 446 void evrpc_pool_remove_connection(struct evrpc_pool *pool, 447 struct evhttp_connection *evcon); 448 449 /** 450 * Sets the timeout in secs after which a request has to complete. The 451 * RPC is completely aborted if it does not complete by then. Setting 452 * the timeout to 0 means that it never timeouts and can be used to 453 * implement callback type RPCs. 454 * 455 * Any connection already in the pool will be updated with the new 456 * timeout. Connections added to the pool after set_timeout has be 457 * called receive the pool timeout only if no timeout has been set 458 * for the connection itself. 459 * 460 * @param pool a pointer to a struct evrpc_pool object 461 * @param timeout_in_secs the number of seconds after which a request should 462 * timeout and a failure be returned to the callback. 463 */ 464 EVENT2_EXPORT_SYMBOL 465 void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs); 466 467 /** 468 * Hooks for changing the input and output of RPCs; this can be used to 469 * implement compression, authentication, encryption, ... 470 */ 471 472 enum EVRPC_HOOK_TYPE { 473 EVRPC_INPUT, /**< apply the function to an input hook */ 474 EVRPC_OUTPUT /**< apply the function to an output hook */ 475 }; 476 477 #ifndef _WIN32 478 /** Deprecated alias for EVRPC_INPUT. Not available on windows, where it 479 * conflicts with platform headers. */ 480 #define INPUT EVRPC_INPUT 481 /** Deprecated alias for EVRPC_OUTPUT. Not available on windows, where it 482 * conflicts with platform headers. */ 483 #define OUTPUT EVRPC_OUTPUT 484 #endif 485 486 /** 487 * Return value from hook processing functions 488 */ 489 490 enum EVRPC_HOOK_RESULT { 491 EVRPC_TERMINATE = -1, /**< indicates the rpc should be terminated */ 492 EVRPC_CONTINUE = 0, /**< continue processing the rpc */ 493 EVRPC_PAUSE = 1 /**< pause processing request until resumed */ 494 }; 495 496 /** adds a processing hook to either an rpc base or rpc pool 497 * 498 * If a hook returns TERMINATE, the processing is aborted. On CONTINUE, 499 * the request is immediately processed after the hook returns. If the 500 * hook returns PAUSE, request processing stops until evrpc_resume_request() 501 * has been called. 502 * 503 * The add functions return handles that can be used for removing hooks. 504 * 505 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 506 * @param hook_type either INPUT or OUTPUT 507 * @param cb the callback to call when the hook is activated 508 * @param cb_arg an additional argument for the callback 509 * @return a handle to the hook so it can be removed later 510 * @see evrpc_remove_hook() 511 */ 512 EVENT2_EXPORT_SYMBOL 513 void *evrpc_add_hook(void *vbase, 514 enum EVRPC_HOOK_TYPE hook_type, 515 int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *), 516 void *cb_arg); 517 518 /** removes a previously added hook 519 * 520 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 521 * @param hook_type either INPUT or OUTPUT 522 * @param handle a handle returned by evrpc_add_hook() 523 * @return 1 on success or 0 on failure 524 * @see evrpc_add_hook() 525 */ 526 EVENT2_EXPORT_SYMBOL 527 int evrpc_remove_hook(void *vbase, 528 enum EVRPC_HOOK_TYPE hook_type, 529 void *handle); 530 531 /** resume a paused request 532 * 533 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 534 * @param ctx the context pointer provided to the original hook call 535 */ 536 EVENT2_EXPORT_SYMBOL 537 int evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); 538 539 /** adds meta data to request 540 * 541 * evrpc_hook_add_meta() allows hooks to add meta data to a request. for 542 * a client request, the meta data can be inserted by an outgoing request hook 543 * and retrieved by the incoming request hook. 544 * 545 * @param ctx the context provided to the hook call 546 * @param key a NUL-terminated c-string 547 * @param data the data to be associated with the key 548 * @param data_size the size of the data 549 */ 550 EVENT2_EXPORT_SYMBOL 551 void evrpc_hook_add_meta(void *ctx, const char *key, 552 const void *data, size_t data_size); 553 554 /** retrieves meta data previously associated 555 * 556 * evrpc_hook_find_meta() can be used to retrieve meta data associated to a 557 * request by a previous hook. 558 * @param ctx the context provided to the hook call 559 * @param key a NUL-terminated c-string 560 * @param data pointer to a data pointer that will contain the retrieved data 561 * @param data_size pointer to the size of the data 562 * @return 0 on success or -1 on failure 563 */ 564 EVENT2_EXPORT_SYMBOL 565 int evrpc_hook_find_meta(void *ctx, const char *key, 566 void **data, size_t *data_size); 567 568 /** 569 * returns the connection object associated with the request 570 * 571 * @param ctx the context provided to the hook call 572 * @return a pointer to the evhttp_connection object or NULL if an error 573 * occurred 574 */ 575 EVENT2_EXPORT_SYMBOL 576 struct evhttp_connection *evrpc_hook_get_connection(void *ctx); 577 578 /** 579 Function for sending a generic RPC request. 580 581 Do not call this function directly, use EVRPC_MAKE_REQUEST() instead. 582 583 @see EVRPC_MAKE_REQUEST() 584 */ 585 EVENT2_EXPORT_SYMBOL 586 int evrpc_send_request_generic(struct evrpc_pool *pool, 587 void *request, void *reply, 588 void (*cb)(struct evrpc_status *, void *, void *, void *), 589 void *cb_arg, 590 const char *rpcname, 591 void (*req_marshal)(struct evbuffer *, void *), 592 void (*rpl_clear)(void *), 593 int (*rpl_unmarshal)(void *, struct evbuffer *)); 594 595 /** 596 Function for registering a generic RPC with the RPC base. 597 598 Do not call this function directly, use EVRPC_REGISTER() instead. 599 600 @see EVRPC_REGISTER() 601 */ 602 EVENT2_EXPORT_SYMBOL 603 int evrpc_register_generic(struct evrpc_base *base, const char *name, 604 void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, 605 void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), 606 int (*req_unmarshal)(void *, struct evbuffer *), 607 void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), 608 int (*rpl_complete)(void *), 609 void (*rpl_marshal)(struct evbuffer *, void *)); 610 611 /** accessors for obscure and undocumented functionality */ 612 EVENT2_EXPORT_SYMBOL 613 struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx); 614 EVENT2_EXPORT_SYMBOL 615 void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx, 616 struct evrpc_pool *pool); 617 EVENT2_EXPORT_SYMBOL 618 void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx, 619 void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg), 620 void *cb_arg); 621 622 #ifdef __cplusplus 623 } 624 #endif 625 626 #endif /* EVENT2_RPC_H_INCLUDED_ */ 627