diff options
author | Simo Sorce <idra@samba.org> | 2011-08-16 09:30:28 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2011-08-21 09:05:05 -0400 |
commit | ee0c69a25e7a0dca0c54989b1d6887a114d93ed4 (patch) | |
tree | e14825b26c28a5d196c9aadad0c73f577e1f2e3d /source3/printing/spoolssd.c | |
parent | 07238713722c7454b87ed9c99d65c37ad3bcee85 (diff) | |
download | samba-ee0c69a25e7a0dca0c54989b1d6887a114d93ed4.tar.gz samba-ee0c69a25e7a0dca0c54989b1d6887a114d93ed4.tar.xz samba-ee0c69a25e7a0dca0c54989b1d6887a114d93ed4.zip |
s3-prefork: do not use a lock_fd, just race on accept()
We used a lock mimicking what apache does for preforked children.
But it doesn't work properly in our case because we do not stop once a request
has been served. Clients are allowed to perform multiple requests and keep the
connection open.
This means that if we allow multiple clients per children, then a child could
take the lock and then be asked to do a long or even locking operation by a
client it already is serving. This woulkd cause the whole server to deadlock,
as the child is now busy and also holding on the lock.
Using a race on accept() by having a tevent_fd on the listening socket wait
for read events we never deadlock. At most we cause a bit of contention among
children. But in the generic case connections are much less frequent for us as
clients tend to be long lived. So the little contention we may have is not a
big deal.
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Simo Sorce <idra@samba.org>
Diffstat (limited to 'source3/printing/spoolssd.c')
-rw-r--r-- | source3/printing/spoolssd.c | 20 |
1 files changed, 3 insertions, 17 deletions
diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index 3bae7c3197..e1052ad1f5 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -353,7 +353,6 @@ struct spoolss_children_data { struct pf_worker_data *pf; int listen_fd_size; int *listen_fds; - int lock_fd; bool listening; }; @@ -366,7 +365,6 @@ static int spoolss_children_main(struct tevent_context *ev_ctx, int child_id, int listen_fd_size, int *listen_fds, - int lock_fd, void *private_data) { struct spoolss_children_data *data; @@ -385,7 +383,6 @@ static int spoolss_children_main(struct tevent_context *ev_ctx, data->pf = pf; data->ev_ctx = ev_ctx; data->msg_ctx = msg_ctx; - data->lock_fd = lock_fd; data->listen_fd_size = listen_fd_size; data->listen_fds = listen_fds; data->listening = false; @@ -465,8 +462,7 @@ static void spoolss_next_client(void *pvt) req = prefork_listen_send(next, data->ev_ctx, data->pf, data->listen_fd_size, - data->listen_fds, - data->lock_fd); + data->listen_fds); if (!req) { DEBUG(1, ("Failed to make listening request!?\n")); talloc_free(next); @@ -495,18 +491,8 @@ static void spoolss_handle_client(struct tevent_req *req) /* we are done listening */ data->listening = false; - if (ret > 0) { - DEBUG(1, ("Failed to accept client connection!\n")); - /* bail out if we are not serving any other client */ - if (data->pf->num_clients == 0) { - data->pf->status = PF_WORKER_EXITING; - } - return; - } - - if (ret == -2) { - DEBUG(1, ("Server asks us to die!\n")); - data->pf->status = PF_WORKER_EXITING; + if (ret != 0) { + DEBUG(6, ("No client connection was available after all!\n")); return; } |