mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
r11487: thanks to make test I noticed a dead lock bug, in the last change,
this only happens with socket_wrapper as socket_connect() returns NT_STATUS_OK instead of NT_STATUS_MORE_PROCESSING_REQUIRED, and we missed to replace the fde event handler... metze
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
bf0b96f057
commit
f04001f280
@ -433,7 +433,7 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req)
|
|||||||
return req->status;
|
return req->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wrepl_request_trigger(struct wrepl_request *req);
|
static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
connect a wrepl_socket to a WINS server
|
connect a wrepl_socket to a WINS server
|
||||||
@ -450,7 +450,7 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
|
|||||||
req->wrepl_socket = wrepl_socket;
|
req->wrepl_socket = wrepl_socket;
|
||||||
req->state = WREPL_REQUEST_RECV;
|
req->state = WREPL_REQUEST_RECV;
|
||||||
|
|
||||||
DLIST_ADD(wrepl_socket->recv_queue, req);
|
DLIST_ADD_END(wrepl_socket->recv_queue, req, struct wrepl_request *);
|
||||||
|
|
||||||
talloc_set_destructor(req, wrepl_request_destructor);
|
talloc_set_destructor(req, wrepl_request_destructor);
|
||||||
|
|
||||||
@ -460,11 +460,21 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
|
|||||||
|
|
||||||
status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip,
|
status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip,
|
||||||
WINS_REPLICATION_PORT, 0);
|
WINS_REPLICATION_PORT, 0);
|
||||||
|
if (NT_STATUS_IS_OK(status)) {
|
||||||
|
talloc_free(wrepl_socket->fde);
|
||||||
|
|
||||||
|
wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket,
|
||||||
|
socket_get_fd(wrepl_socket->sock),
|
||||||
|
EVENT_FD_WRITE,
|
||||||
|
wrepl_handler, wrepl_socket);
|
||||||
|
if (wrepl_socket->fde == NULL) {
|
||||||
|
status = NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||||
req->wrepl_socket = wrepl_socket;
|
req->wrepl_socket = wrepl_socket;
|
||||||
req->state = WREPL_REQUEST_ERROR;
|
wrepl_request_trigger(req, status);
|
||||||
req->status = status;
|
|
||||||
wrepl_request_trigger(req);
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,9 +510,6 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed
|
|||||||
struct timeval t, void *ptr)
|
struct timeval t, void *ptr)
|
||||||
{
|
{
|
||||||
struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request);
|
struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request);
|
||||||
struct wrepl_socket *wrepl_socket = req->wrepl_socket;
|
|
||||||
DLIST_REMOVE(wrepl_socket->send_queue, req);
|
|
||||||
DLIST_REMOVE(wrepl_socket->recv_queue, req);
|
|
||||||
if (req->async.fn) {
|
if (req->async.fn) {
|
||||||
req->async.fn(req);
|
req->async.fn(req);
|
||||||
}
|
}
|
||||||
@ -511,8 +518,23 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed
|
|||||||
/*
|
/*
|
||||||
trigger an immediate event on a wrepl_request
|
trigger an immediate event on a wrepl_request
|
||||||
*/
|
*/
|
||||||
static void wrepl_request_trigger(struct wrepl_request *req)
|
static void wrepl_request_trigger(struct wrepl_request *req, NTSTATUS status)
|
||||||
{
|
{
|
||||||
|
if (req->state == WREPL_REQUEST_SEND) {
|
||||||
|
DLIST_REMOVE(req->wrepl_socket->send_queue, req);
|
||||||
|
}
|
||||||
|
if (req->state == WREPL_REQUEST_RECV) {
|
||||||
|
DLIST_REMOVE(req->wrepl_socket->recv_queue, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
req->state = WREPL_REQUEST_ERROR;
|
||||||
|
} else {
|
||||||
|
req->state = WREPL_REQUEST_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->status = status;
|
||||||
|
|
||||||
/* a zero timeout means immediate */
|
/* a zero timeout means immediate */
|
||||||
event_add_timed(req->wrepl_socket->event_ctx,
|
event_add_timed(req->wrepl_socket->event_ctx,
|
||||||
req, timeval_zero(),
|
req, timeval_zero(),
|
||||||
@ -532,17 +554,19 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket,
|
|||||||
req = talloc_zero(wrepl_socket, struct wrepl_request);
|
req = talloc_zero(wrepl_socket, struct wrepl_request);
|
||||||
if (req == NULL) goto failed;
|
if (req == NULL) goto failed;
|
||||||
|
|
||||||
if (wrepl_socket->dead) {
|
|
||||||
req->wrepl_socket = wrepl_socket;
|
|
||||||
req->state = WREPL_REQUEST_ERROR;
|
|
||||||
req->status = NT_STATUS_INVALID_CONNECTION;
|
|
||||||
wrepl_request_trigger(req);
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->wrepl_socket = wrepl_socket;
|
req->wrepl_socket = wrepl_socket;
|
||||||
req->state = WREPL_REQUEST_SEND;
|
req->state = WREPL_REQUEST_SEND;
|
||||||
|
|
||||||
|
DLIST_ADD_END(wrepl_socket->send_queue, req, struct wrepl_request *);
|
||||||
|
|
||||||
|
talloc_set_destructor(req, wrepl_request_destructor);
|
||||||
|
|
||||||
|
if (wrepl_socket->dead) {
|
||||||
|
req->wrepl_socket = wrepl_socket;
|
||||||
|
wrepl_request_trigger(req, NT_STATUS_INVALID_CONNECTION);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
wrap.packet = *packet;
|
wrap.packet = *packet;
|
||||||
req->status = ndr_push_struct_blob(&req->buffer, req, &wrap,
|
req->status = ndr_push_struct_blob(&req->buffer, req, &wrap,
|
||||||
(ndr_push_flags_fn_t)ndr_push_wrepl_wrap);
|
(ndr_push_flags_fn_t)ndr_push_wrepl_wrap);
|
||||||
@ -553,10 +577,6 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket,
|
|||||||
NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet);
|
NDR_PRINT_DEBUG(wrepl_packet, &wrap.packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLIST_ADD(wrepl_socket->send_queue, req);
|
|
||||||
|
|
||||||
talloc_set_destructor(req, wrepl_request_destructor);
|
|
||||||
|
|
||||||
if (wrepl_socket->request_timeout > 0) {
|
if (wrepl_socket->request_timeout > 0) {
|
||||||
req->te = event_add_timed(wrepl_socket->event_ctx, req,
|
req->te = event_add_timed(wrepl_socket->event_ctx, req,
|
||||||
timeval_current_ofs(wrepl_socket->request_timeout, 0),
|
timeval_current_ofs(wrepl_socket->request_timeout, 0),
|
||||||
|
Reference in New Issue
Block a user