summaryrefslogtreecommitdiff
path: root/source4/libcli/wrepl
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-11-03 18:38:41 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:45:44 -0500
commit6dafef03011865b9452736a417cbc5938714c13b (patch)
treeb4badac030d185e9e7d4072f03be09cce5d9b974 /source4/libcli/wrepl
parent536e68dbee1fcb404230b0fd6a9a050b7e4e9ee8 (diff)
downloadsamba-6dafef03011865b9452736a417cbc5938714c13b.tar.gz
samba-6dafef03011865b9452736a417cbc5938714c13b.tar.bz2
samba-6dafef03011865b9452736a417cbc5938714c13b.zip
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 used to be commit f04001f28007ad6bbecdcdf0d1d5887e378d2467)
Diffstat (limited to 'source4/libcli/wrepl')
-rw-r--r--source4/libcli/wrepl/winsrepl.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c
index bf894c6ad0..5658a2cc03 100644
--- a/source4/libcli/wrepl/winsrepl.c
+++ b/source4/libcli/wrepl/winsrepl.c
@@ -433,7 +433,7 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req)
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 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
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 @@ struct wrepl_request *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
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 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed
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 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed
/*
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 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket,
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 @@ struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket,
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),