Fix bug 5334
authorVolker Lendecke <vl@samba.org>
Tue, 18 Mar 2008 12:20:10 +0000 (13:20 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 18 Mar 2008 12:49:46 +0000 (13:49 +0100)
I did not test with a zero length file :-)
(This used to be commit 7d7a73944c2dcf078f7bc8de65d575f32f9aa851)

source3/include/async_req.h
source3/lib/async_req.c
source3/libsmb/clireadwrite.c

index 6df53602b26a063f1dedc8f488bc6031870b7081..fb463d5b9a172145bb1149fbce8f18540c0a48c1 100644 (file)
@@ -74,6 +74,13 @@ void async_req_done(struct async_req *req);
  */
 void async_req_error(struct async_req *req, NTSTATUS status);
 
+/*
+ * If a request is finished or ends in error even before it has the chance to
+ * trigger the event loop, post a status. This creates an immediate timed
+ * event to call the async function if there is any.
+ */
+bool async_post_status(struct async_req *req, NTSTATUS status);
+
 /*
  * Convenience helper to easily check alloc failure within a callback.
  *
index 01154ca436311ef6fedfed0a863b7d05ad143c8c..2e85d9a38d7ec50c19783bc934494121980103a4 100644 (file)
@@ -58,6 +58,36 @@ void async_req_error(struct async_req *req, NTSTATUS status)
        }
 }
 
+static void async_trigger(struct event_context *ev, struct timed_event *te,
+                         const struct timeval *now, void *priv)
+{
+       struct async_req *req = talloc_get_type_abort(priv, struct async_req);
+
+       TALLOC_FREE(te);
+       if (NT_STATUS_IS_OK(req->status)) {
+               async_req_done(req);
+       }
+       else {
+               async_req_error(req, req->status);
+       }
+}
+
+bool async_post_status(struct async_req *req, NTSTATUS status)
+{
+       /*
+        * Used if a request is finished before it even started
+        */
+
+       req->status = status;
+
+       if (event_add_timed(req->event_ctx, req, timeval_zero(),
+                           "async_trigger",
+                           async_trigger, req) == NULL) {
+               return false;
+       }
+       return true;
+}
+
 bool async_req_nomem(const void *p, struct async_req *req)
 {
        if (p != NULL) {
index 9bd81706730798914a4136b6068d252f8bdaaa1d..13c024a26427bedf600c22227c904088a0260744 100644 (file)
@@ -262,6 +262,14 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli,
 
        state->pushed = 0;
        state->top_req = 0;
+
+       if (size == 0) {
+               if (!async_post_status(result, NT_STATUS_OK)) {
+                       goto failed;
+               }
+               return result;
+       }
+
        state->chunk_size = cli_read_max_bufsize(cli);
 
        state->num_reqs = MAX(window_size/state->chunk_size, 1);