1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-25 17:57:42 +03:00

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.
This commit is contained in:
Simo Sorce 2009-02-28 15:44:30 -05:00
parent 04a2b455a0
commit 67d41d0fc7
8 changed files with 190 additions and 164 deletions

View File

@ -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;

View File

@ -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;
#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)
/**
* @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;
typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *);
/**
* @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;
};
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);

View File

@ -25,6 +25,99 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;