Author: metze Date: 2005-11-03 18:38:41 +0000 (Thu, 03 Nov 2005) New Revision: 11487
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=11487 Log: 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 Modified: branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c Changeset: Modified: branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c =================================================================== --- branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c 2005-11-03 18:01:47 UTC (rev 11486) +++ branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c 2005-11-03 18:38:41 UTC (rev 11487) @@ -433,7 +433,7 @@ 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 @@ -450,7 +450,7 @@ req->wrepl_socket = wrepl_socket; 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); @@ -460,11 +460,21 @@ status = socket_connect(wrepl_socket->sock, our_ip, 0, peer_ip, 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)) { req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_ERROR; - req->status = status; - wrepl_request_trigger(req); + wrepl_request_trigger(req, status); return req; } @@ -500,9 +510,6 @@ struct timeval t, void *ptr) { 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) { req->async.fn(req); } @@ -511,8 +518,23 @@ /* 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 */ event_add_timed(req->wrepl_socket->event_ctx, req, timeval_zero(), @@ -532,17 +554,19 @@ req = talloc_zero(wrepl_socket, struct wrepl_request); if (req == NULL) goto failed; + req->wrepl_socket = wrepl_socket; + 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; - req->state = WREPL_REQUEST_ERROR; - req->status = NT_STATUS_INVALID_CONNECTION; - wrepl_request_trigger(req); + wrepl_request_trigger(req, NT_STATUS_INVALID_CONNECTION); return req; } - req->wrepl_socket = wrepl_socket; - req->state = WREPL_REQUEST_SEND; - wrap.packet = *packet; req->status = ndr_push_struct_blob(&req->buffer, req, &wrap, (ndr_push_flags_fn_t)ndr_push_wrepl_wrap); @@ -553,10 +577,6 @@ 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) { req->te = event_add_timed(wrepl_socket->event_ctx, req, timeval_current_ofs(wrepl_socket->request_timeout, 0),
