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), 

Reply via email to