From 67d41d0fc7567cf141b12e866dd227d393e33551 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 28 Feb 2009 15:44:30 -0500 Subject: Make struct tevent_req opaque Move struct tevent_req in tevent_internal, and ad getters and setters for private data and the callback function. This patch also renames 'private_state' into 'data'. What is held in this pointer is in fact data and not a state like enum tevent_req_state. Calling it 'state' is confusing. The functions addedd are: tevent_req_set_callback() - sets req->async.fn and req->async.private_data tevent_req_set_print_fn() - sets req->private_print tevent_req_callback_data() - gets req->async.private_data tevent_req_data() - gets rea->data This way it is much simpler to keep API/ABI compatibility in the future. --- lib/async_req/async_sock.c | 40 ++++++------- lib/tevent/tevent.h | 102 ++++---------------------------- lib/tevent/tevent_internal.h | 93 +++++++++++++++++++++++++++++ lib/tevent/tevent_req.c | 42 +++++++++---- source3/lib/util_sock.c | 25 ++++---- source3/lib/wb_reqtrans.c | 28 ++++----- source3/rpc_client/rpc_transport_sock.c | 14 ++--- source3/rpc_server/srv_pipe_hnd.c | 14 ++--- 8 files changed, 192 insertions(+), 166 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 1f48697f26..424da952eb 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -123,8 +123,8 @@ static void async_send_handler(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); - struct async_send_state *state = talloc_get_type_abort( - req->private_state, struct async_send_state); + struct async_send_state *state = + tevent_req_data(req, struct async_send_state); state->sent = send(state->fd, state->buf, state->len, state->flags); if (state->sent == -1) { @@ -136,8 +136,8 @@ static void async_send_handler(struct tevent_context *ev, ssize_t async_send_recv(struct tevent_req *req, int *perrno) { - struct async_send_state *state = talloc_get_type_abort( - req->private_state, struct async_send_state); + struct async_send_state *state = + tevent_req_data(req, struct async_send_state); if (tevent_req_is_unix_error(req, perrno)) { return -1; @@ -189,8 +189,8 @@ static void async_recv_handler(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); - struct async_recv_state *state = talloc_get_type_abort( - req->private_state, struct async_recv_state); + struct async_recv_state *state = + tevent_req_data(req, struct async_recv_state); state->received = recv(state->fd, state->buf, state->len, state->flags); @@ -203,8 +203,8 @@ static void async_recv_handler(struct tevent_context *ev, ssize_t async_recv_recv(struct tevent_req *req, int *perrno) { - struct async_recv_state *state = talloc_get_type_abort( - req->private_state, struct async_recv_state); + struct async_recv_state *state = + tevent_req_data(req, struct async_recv_state); if (tevent_req_is_unix_error(req, perrno)) { return -1; @@ -317,8 +317,8 @@ static void async_connect_connected(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( priv, struct tevent_req); - struct async_connect_state *state = talloc_get_type_abort( - req->private_state, struct async_connect_state); + struct async_connect_state *state = + tevent_req_data(req, struct async_connect_state); TALLOC_FREE(fde); @@ -352,8 +352,8 @@ static void async_connect_connected(struct tevent_context *ev, int async_connect_recv(struct tevent_req *req, int *perrno) { - struct async_connect_state *state = talloc_get_type_abort( - req->private_state, struct async_connect_state); + struct async_connect_state *state = + tevent_req_data(req, struct async_connect_state); int err; fcntl(state->fd, F_SETFL, state->old_sockflags); @@ -420,8 +420,8 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); - struct writev_state *state = talloc_get_type_abort( - req->private_state, struct writev_state); + struct writev_state *state = + tevent_req_data(req, struct writev_state); size_t to_write, written; int i; @@ -467,8 +467,8 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, ssize_t writev_recv(struct tevent_req *req, int *perrno) { - struct writev_state *state = talloc_get_type_abort( - req->private_state, struct writev_state); + struct writev_state *state = + tevent_req_data(req, struct writev_state); if (tevent_req_is_unix_error(req, perrno)) { return -1; @@ -531,8 +531,8 @@ static void read_packet_handler(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); - struct read_packet_state *state = talloc_get_type_abort( - req->private_state, struct read_packet_state); + struct read_packet_state *state = + tevent_req_data(req, struct read_packet_state); size_t total = talloc_get_size(state->buf); ssize_t nread, more; uint8_t *tmp; @@ -584,8 +584,8 @@ static void read_packet_handler(struct tevent_context *ev, ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **pbuf, int *perrno) { - struct read_packet_state *state = talloc_get_type_abort( - req->private_state, struct read_packet_state); + struct read_packet_state *state = + tevent_req_data(req, struct read_packet_state); if (tevent_req_is_unix_error(req, perrno)) { return -1; diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 8c119ffb8e..5089d18ec2 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -183,98 +183,22 @@ enum tevent_req_state { * finished. This can happen while the completion function is called. */ -struct tevent_req { - /** - * @brief What to do on completion - * - * This is used for the user of an async request, fn is called when - * the request completes, either successfully or with an error. - */ - struct { - /** - * @brief Completion function - * Completion function, to be filled by the API user - */ - void (*fn)(struct tevent_req *); - /** - * @brief Private data for the completion function - */ - void *private_data; - } async; +struct tevent_req; - /** - * @brief Private state pointer for the actual implementation - * - * The implementation doing the work for the async request needs a - * current state like for example a fd event. The user of an async - * request should not touch this. - */ - void *private_state; +typedef void (*tevent_req_fn)(struct tevent_req *); - /** - * @brief A function to overwrite the default print function - * - * The implementation doing the work may want to imeplement a - * custom function to print the text representation of the async - * request. - */ - char *(*private_print)(struct tevent_req *req, TALLOC_CTX *mem_ctx); +void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt); +void *_tevent_req_callback_data(struct tevent_req *req); +void *_tevent_req_data(struct tevent_req *req); - /** - * @brief Internal state of the request - * - * Callers should only access this via functions and never directly. - */ - struct { - /** - * @brief The talloc type of the private_state pointer - * - * This is filled by the tevent_req_create() macro. - * - * This for debugging only. - */ - const char *private_type; - - /** - * @brief The location where the request was created - * - * This uses the __location__ macro via the tevent_req_create() - * macro. - * - * This for debugging only. - */ - const char *location; - - /** - * @brief The external state - will be queried by the caller - * - * While the async request is being processed, state will remain in - * TEVENT_REQ_IN_PROGRESS. A request is finished if - * req->state>=TEVENT_REQ_DONE. - */ - enum tevent_req_state state; - - /** - * @brief status code when finished - * - * This status can be queried in the async completion function. It - * will be set to 0 when everything went fine. - */ - uint64_t error; - - /** - * @brief the timer event if tevent_req_post was used - * - */ - struct tevent_timer *trigger; - - /** - * @brief the timer event if tevent_req_set_timeout was used - * - */ - struct tevent_timer *timer; - } internal; -}; +#define tevent_req_callback_data(_req, _type) \ + talloc_get_type_abort(_tevent_req_callback_data(_req), _type) +#define tevent_req_data(_req, _type) \ + talloc_get_type_abort(_tevent_req_data(_req), _type) + +typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *); + +void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn); char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index 758bdb4628..fa73b22a48 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -25,6 +25,99 @@ License along with this library; if not, see . */ +struct tevent_req { + /** + * @brief What to do on completion + * + * This is used for the user of an async request, fn is called when + * the request completes, either successfully or with an error. + */ + struct { + /** + * @brief Completion function + * Completion function, to be filled by the API user + */ + tevent_req_fn fn; + /** + * @brief Private data for the completion function + */ + void *private_data; + } async; + + /** + * @brief Private state pointer for the actual implementation + * + * The implementation doing the work for the async request needs to + * keep around current data like for example a fd event. The user of + * an async request should not touch this. + */ + void *data; + + /** + * @brief A function to overwrite the default print function + * + * The implementation doing the work may want to imeplement a + * custom function to print the text representation of the async + * request. + */ + tevent_req_print_fn private_print; + + /** + * @brief Internal state of the request + * + * Callers should only access this via functions and never directly. + */ + struct { + /** + * @brief The talloc type of the data pointer + * + * This is filled by the tevent_req_create() macro. + * + * This for debugging only. + */ + const char *private_type; + + /** + * @brief The location where the request was created + * + * This uses the __location__ macro via the tevent_req_create() + * macro. + * + * This for debugging only. + */ + const char *location; + + /** + * @brief The external state - will be queried by the caller + * + * While the async request is being processed, state will remain in + * TEVENT_REQ_IN_PROGRESS. A request is finished if + * req->state>=TEVENT_REQ_DONE. + */ + enum tevent_req_state state; + + /** + * @brief status code when finished + * + * This status can be queried in the async completion function. It + * will be set to 0 when everything went fine. + */ + uint64_t error; + + /** + * @brief the timer event if tevent_req_post was used + * + */ + struct tevent_timer *trigger; + + /** + * @brief the timer event if tevent_req_set_timeout was used + * + */ + struct tevent_timer *timer; + } internal; +}; + struct tevent_ops { /* conntext init */ int (*context_init)(struct tevent_context *ev); diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index e243c7de5d..9b3e00ec8f 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -47,8 +47,8 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) req->internal.state, (unsigned long long)req->internal.error, (unsigned long long)req->internal.error, - talloc_get_name(req->private_state), - req->private_state, + talloc_get_name(req->data), + req->data, req->internal.timer ); } @@ -81,14 +81,14 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) */ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, - void *pstate, - size_t state_size, + void *pdata, + size_t data_size, const char *type, const char *location) { struct tevent_req *req; - void **ppstate = (void **)pstate; - void *state; + void **ppdata = (void **)pdata; + void *data; req = talloc_zero(mem_ctx, struct tevent_req); if (req == NULL) { @@ -98,16 +98,16 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, req->internal.location = location; req->internal.state = TEVENT_REQ_IN_PROGRESS; - state = talloc_size(req, state_size); - if (state == NULL) { + data = talloc_size(req, data_size); + if (data == NULL) { talloc_free(req); return NULL; } - talloc_set_name_const(state, type); + talloc_set_name_const(data, type); - req->private_state = state; + req->data = data; - *ppstate = state; + *ppdata = data; return req; } @@ -314,3 +314,23 @@ bool tevent_req_set_endtime(struct tevent_req *req, return true; } +void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) +{ + req->async.fn = fn; + req->async.private_data = pvt; +} + +void *_tevent_req_callback_data(struct tevent_req *req) +{ + return req->async.private_data; +} + +void *_tevent_req_data(struct tevent_req *req) +{ + return req->data; +} + +void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) +{ + req->private_print = fn; +} diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 6e75a67a85..3604be369f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1033,8 +1033,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, timeval_current_ofs(0, state->wait_nsec))) { goto fail; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, open_socket_out_connected, result); return result; post_status: @@ -1047,10 +1046,10 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, static void open_socket_out_connected(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.private_data, struct tevent_req); - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_state, struct open_socket_out_state); + struct tevent_req *req = + tevent_req_callback_data(subreq, struct tevent_req); + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); int ret; int sys_errno; @@ -1089,8 +1088,7 @@ static void open_socket_out_connected(struct tevent_req *subreq) tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, open_socket_out_connected, req); return; } @@ -1107,8 +1105,8 @@ static void open_socket_out_connected(struct tevent_req *subreq) NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd) { - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_state, struct open_socket_out_state); + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { @@ -1217,14 +1215,13 @@ static void open_socket_out_defer_waited(struct async_req *subreq) if (async_req_nomem(subreq2, req)) { return; } - subreq2->async.fn = open_socket_out_defer_connected; - subreq2->async.private_data = req; + tevent_req_set_callback(subreq2, open_socket_out_defer_connected, req); } static void open_socket_out_defer_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct open_socket_out_defer_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_defer_state); NTSTATUS status; diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 65906dcb91..63a25fb896 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -103,8 +103,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, goto nomem; } - subreq->async.fn = wb_req_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_req_read_done, result); return result; nomem: TALLOC_FREE(result); @@ -140,8 +139,8 @@ static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) static void wb_req_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct req_read_state *state = talloc_get_type_abort( req->private_data, struct req_read_state); int err; @@ -213,8 +212,7 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_req_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(wb_req_write_done, result); return result; fail: @@ -224,8 +222,8 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, static void wb_req_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); int err; ssize_t ret; @@ -266,8 +264,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto nomem; } - subreq->async.fn = wb_resp_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_read_done, result); return result; nomem: @@ -293,8 +290,8 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) static void wb_resp_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct resp_read_state *state = talloc_get_type_abort( req->private_data, struct resp_read_state); uint8_t *buf; @@ -367,8 +364,7 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_resp_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_write_done, result); return result; fail: @@ -378,8 +374,8 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, static void wb_resp_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_re_callback_data(subreq, struct async_req); int err; ssize_t ret; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 658ffe30d6..b1d9d8fbe1 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -61,8 +61,7 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_sock_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, rpc_sock_read_done, result); return result; fail: TALLOC_FREE(result); @@ -71,8 +70,8 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, static void rpc_sock_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct rpc_sock_read_state *state = talloc_get_type_abort( req->private_data, struct rpc_sock_read_state); int err; @@ -123,8 +122,7 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_sock_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, rpc_sock_write_done, result); return result; fail: TALLOC_FREE(result); @@ -133,8 +131,8 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, static void rpc_sock_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct rpc_sock_write_state *state = talloc_get_type_abort( req->private_data, struct rpc_sock_write_state); int err; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 33e89c8acb..a5d059c06a 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1247,14 +1247,13 @@ static void np_write_trigger(struct async_req *req) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = np_write_done; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, np_write_done, req); } static void np_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); ssize_t received; @@ -1398,14 +1397,13 @@ static void np_read_trigger(struct async_req *req) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = np_read_done; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, np_read_done, req); } static void np_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); ssize_t received; -- cgit