From 6909b5b92ab0720121f8f95eab0ee1ab2e1c5080 Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Wed, 3 Dec 2008 10:17:44 +0000 Subject: [PATCH] Deal with c_req send errors asynchronously if a c_req wouldn't send (maybe due to bad trasnport or some other error) and the caller still tries to add an async handler for the respons (which now won't happen), add a timer callback instead so the error state can still be reaped asynchronously. --- source4/ntvfs/cifs/vfs_cifs.c | 21 +++++++++++++++++++++ source4/ntvfs/proxy/vfs_proxy.c | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index e615401e513..ce8af1e48ea 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -315,9 +315,30 @@ static void async_simple(struct smbcli_request *c_req) } \ c_req->async.fn = async_fn; \ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ + MAKE_SYNC_ERROR_ASYNC(c_req, NT_STATUS_UNSUCCESSFUL); \ return NT_STATUS_OK; \ } while (0) +static void vasync_timer(struct event_context * ec, struct timed_event *te, + struct timeval tv, void *data) { + struct smbcli_request *c_req = talloc_get_type_abort(data, struct smbcli_request); + + DEBUG(5,("Calling async timer on c_req %p with req %p\n",c_req->async.fn, c_req)); \ + c_req->async.fn(c_req); +} + +#define MAKE_SYNC_ERROR_ASYNC(c_req, error) do { \ + if (c_req && c_req->state >= SMBCLI_REQUEST_DONE) { \ + /* NOTE: the timer struct is allocated against c_req, so if the c_req */ \ + /* handler is called manually, the timer will be destroyed with c_req */ \ + if (! event_add_timed(private->ntvfs->ctx->event_ctx, c_req, \ + timeval_current_ofs(0, 0), \ + vasync_timer, \ + c_req)) return (error); \ + DEBUG(5,("Queueing async timer on c_req %p with req %p\n",c_req->async.fn, c_req)); \ + } \ +} while(0) + #define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) #define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) diff --git a/source4/ntvfs/proxy/vfs_proxy.c b/source4/ntvfs/proxy/vfs_proxy.c index 6094d4b3564..d16411f525b 100644 --- a/source4/ntvfs/proxy/vfs_proxy.c +++ b/source4/ntvfs/proxy/vfs_proxy.c @@ -746,6 +746,7 @@ static void async_simple(struct smbcli_request *c_req) if (!c_req) return (error); \ ASYNC_RECV_TAIL_F_ORPHAN_NE(io, async_fn, file, achain); \ if (! c_req->async.private) return (error); \ + MAKE_SYNC_ERROR_ASYNC(c_req, error); \ } while(0) #define ASYNC_RECV_TAIL_F_ORPHAN_NE(io, async_fn, file, achain) do { \ @@ -786,9 +787,30 @@ static void async_simple(struct smbcli_request *c_req) } \ c_req->async.fn = async_fn; \ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ + MAKE_SYNC_ERROR_ASYNC(c_req, NT_STATUS_UNSUCCESSFUL); \ return NT_STATUS_OK; \ } while (0) +static void vasync_timer(struct event_context * ec, struct timed_event *te, + struct timeval tv, void *data) { + struct smbcli_request *c_req = talloc_get_type_abort(data, struct smbcli_request); + + DEBUG(5,("Calling async timer on c_req %p with req %p\n",c_req->async.fn, c_req)); \ + c_req->async.fn(c_req); +} + +#define MAKE_SYNC_ERROR_ASYNC(c_req, error) do { \ + if (c_req && c_req->state >= SMBCLI_REQUEST_DONE) { \ + /* NOTE: the timer struct is allocated against c_req, so if the c_req */ \ + /* handler is called manually, the timer will be destroyed with c_req */ \ + if (! event_add_timed(private->ntvfs->ctx->event_ctx, c_req, \ + timeval_current_ofs(0, 0), \ + vasync_timer, \ + c_req)) return (error); \ + DEBUG(5,("Queueing async timer on c_req %p with req %p\n",c_req->async.fn, c_req)); \ + } \ +} while(0) + #define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) #define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) -- 2.11.4.GIT