00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _EVRPC_H_
00028 #define _EVRPC_H_
00029
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033
00069 struct evbuffer;
00070 struct event_base;
00071 struct evrpc_req_generic;
00072
00073
00074 struct evrpc {
00075 TAILQ_ENTRY(evrpc) next;
00076
00077
00078 const char* uri;
00079
00080
00081 void *(*request_new)(void);
00082
00083
00084 void (*request_free)(void *);
00085
00086
00087 int (*request_unmarshal)(void *, struct evbuffer *);
00088
00089
00090 void *(*reply_new)(void);
00091
00092
00093 void (*reply_free)(void *);
00094
00095
00096 int (*reply_complete)(void *);
00097
00098
00099 void (*reply_marshal)(struct evbuffer*, void *);
00100
00101
00102 void (*cb)(struct evrpc_req_generic *, void *);
00103 void *cb_arg;
00104
00105
00106 struct evrpc_base *base;
00107 };
00108
00113 #define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname
00114
00115 struct evhttp_request;
00116 struct evrpc_status;
00117
00118
00119 struct evrpc_req_generic {
00120
00121 void *request;
00122
00123
00124 void *reply;
00125
00126
00127
00128
00129
00130 struct evrpc *rpc;
00131
00132
00133
00134
00135 struct evhttp_request* http_req;
00136
00137
00138
00139
00140 void (*done)(struct evrpc_req_generic* rpc);
00141 };
00142
00154 #define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \
00155 EVRPC_STRUCT(rpcname) { \
00156 struct reqstruct* request; \
00157 struct rplystruct* reply; \
00158 struct evrpc* rpc; \
00159 struct evhttp_request* http_req; \
00160 void (*done)(struct evrpc_status *, \
00161 struct evrpc* rpc, void *request, void *reply); \
00162 }; \
00163 int evrpc_send_request_##rpcname(struct evrpc_pool *, \
00164 struct reqstruct *, struct rplystruct *, \
00165 void (*)(struct evrpc_status *, \
00166 struct reqstruct *, struct rplystruct *, void *cbarg), \
00167 void *);
00168
00179 #define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \
00180 int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \
00181 struct reqstruct *request, struct rplystruct *reply, \
00182 void (*cb)(struct evrpc_status *, \
00183 struct reqstruct *, struct rplystruct *, void *cbarg), \
00184 void *cbarg) { \
00185 struct evrpc_status status; \
00186 struct evrpc_request_wrapper *ctx; \
00187 ctx = (struct evrpc_request_wrapper *) \
00188 malloc(sizeof(struct evrpc_request_wrapper)); \
00189 if (ctx == NULL) \
00190 goto error; \
00191 ctx->pool = pool; \
00192 ctx->evcon = NULL; \
00193 ctx->name = strdup(#rpcname); \
00194 if (ctx->name == NULL) { \
00195 free(ctx); \
00196 goto error; \
00197 } \
00198 ctx->cb = (void (*)(struct evrpc_status *, \
00199 void *, void *, void *))cb; \
00200 ctx->cb_arg = cbarg; \
00201 ctx->request = (void *)request; \
00202 ctx->reply = (void *)reply; \
00203 ctx->request_marshal = (void (*)(struct evbuffer *, void *))reqstruct##_marshal; \
00204 ctx->reply_clear = (void (*)(void *))rplystruct##_clear; \
00205 ctx->reply_unmarshal = (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal; \
00206 return (evrpc_make_request(ctx)); \
00207 error: \
00208 memset(&status, 0, sizeof(status)); \
00209 status.error = EVRPC_STATUS_ERR_UNSTARTED; \
00210 (*(cb))(&status, request, reply, cbarg); \
00211 return (-1); \
00212 }
00213
00223 #define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req
00224
00233 #define EVRPC_REQUEST_DONE(rpc_req) do { \
00234 struct evrpc_req_generic *_req = (struct evrpc_req_generic *)(rpc_req); \
00235 _req->done(_req); \
00236 } while (0)
00237
00238
00239
00240 #define EVRPC_REGISTER_OBJECT(rpc, name, request, reply) \
00241 do { \
00242 (rpc)->uri = strdup(#name); \
00243 if ((rpc)->uri == NULL) { \
00244 fprintf(stderr, "failed to register object\n"); \
00245 exit(1); \
00246 } \
00247 (rpc)->request_new = (void *(*)(void))request##_new; \
00248 (rpc)->request_free = (void (*)(void *))request##_free; \
00249 (rpc)->request_unmarshal = (int (*)(void *, struct evbuffer *))request##_unmarshal; \
00250 (rpc)->reply_new = (void *(*)(void))reply##_new; \
00251 (rpc)->reply_free = (void (*)(void *))reply##_free; \
00252 (rpc)->reply_complete = (int (*)(void *))reply##_complete; \
00253 (rpc)->reply_marshal = (void (*)(struct evbuffer*, void *))reply##_marshal; \
00254 } while (0)
00255
00256 struct evrpc_base;
00257 struct evhttp;
00258
00259
00260
00267 struct evrpc_base *evrpc_init(struct evhttp *server);
00268
00277 void evrpc_free(struct evrpc_base *base);
00278
00295 #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \
00296 do { \
00297 struct evrpc* rpc = (struct evrpc *)calloc(1, sizeof(struct evrpc)); \
00298 EVRPC_REGISTER_OBJECT(rpc, name, request, reply); \
00299 evrpc_register_rpc(base, rpc, \
00300 (void (*)(struct evrpc_req_generic*, void *))callback, cbarg); \
00301 } while (0)
00302
00303 int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
00304 void (*)(struct evrpc_req_generic*, void *), void *);
00305
00314 #define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc(base, #name)
00315
00316 int evrpc_unregister_rpc(struct evrpc_base *base, const char *name);
00317
00318
00319
00320
00321
00322 struct evrpc_pool;
00323 struct evhttp_connection;
00324
00328 struct evrpc_status {
00329 #define EVRPC_STATUS_ERR_NONE 0
00330 #define EVRPC_STATUS_ERR_TIMEOUT 1
00331 #define EVRPC_STATUS_ERR_BADPAYLOAD 2
00332 #define EVRPC_STATUS_ERR_UNSTARTED 3
00333 #define EVRPC_STATUS_ERR_HOOKABORTED 4
00334 int error;
00335
00336
00337 struct evhttp_request *http_req;
00338 };
00339
00340 struct evrpc_request_wrapper {
00341 TAILQ_ENTRY(evrpc_request_wrapper) next;
00342
00343
00344 struct evrpc_pool *pool;
00345
00346
00347 struct evhttp_connection *evcon;
00348
00349
00350 struct event ev_timeout;
00351
00352
00353 char *name;
00354
00355
00356 void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg);
00357 void *cb_arg;
00358
00359 void *request;
00360 void *reply;
00361
00362
00363 void (*request_marshal)(struct evbuffer *, void *);
00364
00365
00366 void (*reply_clear)(void *);
00367
00368
00369 int (*reply_unmarshal)(void *, struct evbuffer*);
00370 };
00371
00387 #define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg) \
00388 evrpc_send_request_##name(pool, request, reply, cb, cbarg)
00389
00390 int evrpc_make_request(struct evrpc_request_wrapper *);
00391
00402 struct evrpc_pool *evrpc_pool_new(struct event_base *base);
00408 void evrpc_pool_free(struct evrpc_pool *pool);
00409
00410
00411
00412
00413 void evrpc_pool_add_connection(struct evrpc_pool *,
00414 struct evhttp_connection *);
00415
00431 void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs);
00432
00438 enum EVRPC_HOOK_TYPE {
00439 INPUT,
00440 OUTPUT
00441 };
00442
00456 void *evrpc_add_hook(void *vbase,
00457 enum EVRPC_HOOK_TYPE hook_type,
00458 int (*cb)(struct evhttp_request *, struct evbuffer *, void *),
00459 void *cb_arg);
00460
00469 int evrpc_remove_hook(void *vbase,
00470 enum EVRPC_HOOK_TYPE hook_type,
00471 void *handle);
00472
00473 #ifdef __cplusplus
00474 }
00475 #endif
00476
00477 #endif