1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

lib/tsocket: add tsocket_writev_queue_send/recv()

metze
This commit is contained in:
Stefan Metzmacher 2009-03-11 14:26:15 +01:00
parent 2e44ceaea8
commit 6c8bd1005d
2 changed files with 126 additions and 0 deletions

View File

@ -198,5 +198,12 @@ struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
size_t count);
int tsocket_writev_recv(struct tevent_req *req, int *perrno);
struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
struct tsocket_context *sock,
struct tevent_queue *queue,
const struct iovec *vector,
size_t count);
int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno);
#endif /* _TSOCKET_H */

View File

@ -185,3 +185,122 @@ int tsocket_writev_recv(struct tevent_req *req, int *perrno)
return ret;
}
struct tsocket_writev_queue_state {
/* this structs are owned by the caller */
struct {
struct tsocket_context *sock;
const struct iovec *vector;
size_t count;
} caller;
int ret;
};
static void tsocket_writev_queue_trigger(struct tevent_req *req,
void *private_data);
static void tsocket_writev_queue_done(struct tevent_req *subreq);
/**
* @brief Queue a dgram blob for sending through the socket
* @param[in] mem_ctx The memory context for the result
* @param[in] sock The socket to send data through
* @param[in] queue The existing send queue
* @param[in] vector The iovec vector so write
* @param[in] count The size of the vector
* @retval The async request handle
*
* This function queues a blob for sending to destination through an existing
* dgram socket. The async callback is triggered when the whole blob is
* delivered to the underlying system socket.
*
* The caller needs to make sure that all non-scalar input parameters hang
* arround for the whole lifetime of the request.
*/
struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
struct tsocket_context *sock,
struct tevent_queue *queue,
const struct iovec *vector,
size_t count)
{
struct tevent_req *req;
struct tsocket_writev_queue_state *state;
bool ok;
req = tevent_req_create(mem_ctx, &state,
struct tsocket_writev_queue_state);
if (!req) {
return NULL;
}
state->caller.sock = sock;
state->caller.vector = vector;
state->caller.count = count;
state->ret = -1;
ok = tevent_queue_add(queue,
sock->event.ctx,
req,
tsocket_writev_queue_trigger,
NULL);
if (!ok) {
tevent_req_nomem(NULL, req);
goto post;
}
return req;
post:
return tevent_req_post(req, sock->event.ctx);
}
static void tsocket_writev_queue_trigger(struct tevent_req *req,
void *private_data)
{
struct tsocket_writev_queue_state *state = tevent_req_data(req,
struct tsocket_writev_queue_state);
struct tevent_req *subreq;
subreq = tsocket_writev_send(state->caller.sock,
state,
state->caller.vector,
state->caller.count);
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, tsocket_writev_queue_done ,req);
}
static void tsocket_writev_queue_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct tsocket_writev_queue_state *state = tevent_req_data(req,
struct tsocket_writev_queue_state);
int ret;
int sys_errno;
ret = tsocket_writev_recv(subreq, &sys_errno);
talloc_free(subreq);
if (ret == -1) {
tevent_req_error(req, sys_errno);
return;
}
state->ret = ret;
tevent_req_done(req);
}
int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno)
{
struct tsocket_writev_queue_state *state = tevent_req_data(req,
struct tsocket_writev_queue_state);
int ret;
ret = tsocket_simple_int_recv(req, perrno);
if (ret == 0) {
ret = state->ret;
}
tevent_req_received(req);
return ret;
}