Next step disentangling async_req from NTSTATUS
authorVolker Lendecke <vl@samba.org>
Mon, 2 Feb 2009 16:23:35 +0000 (17:23 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 2 Feb 2009 19:15:03 +0000 (20:15 +0100)
Now I need to document this :-)

lib/async_req/async_req.c
lib/async_req/async_req.h
lib/async_req/async_req_ntstatus.c
lib/async_req/async_req_ntstatus.h
source3/lib/util_sock.c
source3/lib/wb_reqtrans.c
source3/lib/wbclient.c
source3/libsmb/clireadwrite.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/rpc_transport_smbd.c

index 1b9fc55..db47bd9 100644 (file)
@@ -70,6 +70,14 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
        return result;
 }
 
+static void async_req_finish(struct async_req *req, enum async_req_state state)
+{
+       req->state = state;
+       if (req->async.fn != NULL) {
+               req->async.fn(req);
+       }
+}
+
 /**
  * @brief An async request has successfully finished
  * @param[in] req      The finished request
@@ -81,30 +89,23 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
 
 void async_req_done(struct async_req *req)
 {
-       req->error = 0;
-       req->state = ASYNC_REQ_DONE;
-       if (req->async.fn != NULL) {
-               req->async.fn(req);
-       }
+       async_req_finish(req, ASYNC_REQ_DONE);
 }
 
 /**
  * @brief An async request has seen an error
  * @param[in] req      The request with an error
- * @param[in] status   The error code
+ * @param[in] error    The error code
  *
  * async_req_done is to be used by implementors of async requests. When a
  * request can not successfully completed, the implementation should call this
  * function with the appropriate status code.
  */
 
-void async_req_error(struct async_req *req, uint32_t error)
+void async_req_error(struct async_req *req, uint64_t error)
 {
        req->error = error;
-       req->state = ASYNC_REQ_ERROR;
-       if (req->async.fn != NULL) {
-               req->async.fn(req);
-       }
+       async_req_finish(req, ASYNC_REQ_USER_ERROR);
 }
 
 /**
@@ -129,6 +130,32 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te,
        }
 }
 
+/**
+ * @brief Helper function for nomem check
+ * @param[in] p                The pointer to be checked
+ * @param[in] req      The request being processed
+ *
+ * Convenience helper to easily check alloc failure within a callback
+ * implementing the next step of an async request.
+ *
+ * Call pattern would be
+ * \code
+ * p = talloc(mem_ctx, bla);
+ * if (async_req_ntnomem(p, req)) {
+ *     return;
+ * }
+ * \endcode
+ */
+
+bool async_req_nomem(const void *p, struct async_req *req)
+{
+       if (p != NULL) {
+               return false;
+       }
+       async_req_finish(req, ASYNC_REQ_NO_MEMORY);
+       return true;
+}
+
 /**
  * @brief Finish a request before it started processing
  * @param[in] req      The finished request
@@ -143,7 +170,7 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te,
  */
 
 bool async_post_error(struct async_req *req, struct tevent_context *ev,
-                     uint32_t error)
+                     uint64_t error)
 {
        req->error = error;
 
@@ -154,16 +181,17 @@ bool async_post_error(struct async_req *req, struct tevent_context *ev,
        return true;
 }
 
-bool async_req_is_error(struct async_req *req, uint32_t *error)
+bool async_req_is_error(struct async_req *req, enum async_req_state *state,
+                       uint64_t *error)
 {
-       if (req->state < ASYNC_REQ_DONE) {
-               return true;
+       if (req->state == ASYNC_REQ_DONE) {
+               return false;
        }
-       if (req->state == ASYNC_REQ_ERROR) {
+       if (req->state == ASYNC_REQ_USER_ERROR) {
                *error = req->error;
-               return true;
        }
-       return false;
+       *state = req->state;
+       return true;
 }
 
 static void async_req_timedout(struct tevent_context *ev,
@@ -171,18 +199,17 @@ static void async_req_timedout(struct tevent_context *ev,
                               struct timeval now,
                               void *priv)
 {
-       struct async_req *req = talloc_get_type_abort(
-               priv, struct async_req);
+       struct async_req *req = talloc_get_type_abort(priv, struct async_req);
        TALLOC_FREE(te);
-       async_req_nterror(req, NT_STATUS_IO_TIMEOUT);
+       async_req_finish(req, ASYNC_REQ_TIMED_OUT);
 }
 
 bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
                           struct timeval to)
 {
-       return (tevent_add_timer(ev, req,
-                               timeval_current_ofs(to.tv_sec, to.tv_usec),
-                               async_req_timedout, req)
+       return (tevent_add_timer(
+                       ev, req, timeval_current_ofs(to.tv_sec, to.tv_usec),
+                       async_req_timedout, req)
                != NULL);
 }
 
index 19b052a..fc84988 100644 (file)
@@ -40,9 +40,17 @@ enum async_req_state {
         */
        ASYNC_REQ_DONE,
        /**
-        * an error has occured
+        * A user error has occured
         */
-       ASYNC_REQ_ERROR
+       ASYNC_REQ_USER_ERROR,
+       /**
+        * Request timed out
+        */
+       ASYNC_REQ_TIMED_OUT,
+       /**
+        * No memory in between
+        */
+       ASYNC_REQ_NO_MEMORY
 };
 
 /**
@@ -94,7 +102,7 @@ struct async_req {
         * This status can be queried in the async completion function. It
         * will be set to 0 when everything went fine.
         **/
-       uint32_t error;
+       uint64_t error;
 
        /**
         * @brief What to do on completion
@@ -121,12 +129,15 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req);
 
 void async_req_done(struct async_req *req);
 
-void async_req_error(struct async_req *req, uint32_t error);
+void async_req_error(struct async_req *req, uint64_t error);
+
+bool async_req_nomem(const void *p, struct async_req *req);
 
 bool async_post_error(struct async_req *req, struct tevent_context *ev,
-                     uint32_t error);
+                     uint64_t error);
 
-bool async_req_is_error(struct async_req *req, uint32_t *error);
+bool async_req_is_error(struct async_req *req, enum async_req_state *state,
+                       uint64_t *error);
 
 bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
                           struct timeval to);
index dd81026..65bc0f6 100644 (file)
 #include "lib/util/dlinklist.h"
 #include "lib/async_req/async_req_ntstatus.h"
 
-/**
- * @brief Helper function for nomem check
- * @param[in] p                The pointer to be checked
- * @param[in] req      The request being processed
- *
- * Convenience helper to easily check alloc failure within a callback
- * implementing the next step of an async request.
- *
- * Call pattern would be
- * \code
- * p = talloc(mem_ctx, bla);
- * if (async_req_ntnomem(p, req)) {
- *     return;
- * }
- * \endcode
- */
-
-bool async_req_ntnomem(const void *p, struct async_req *req)
-{
-       if (p != NULL) {
-               return false;
-       }
-       async_req_nterror(req, NT_STATUS_NO_MEMORY);
-       return true;
-}
-
 void async_req_nterror(struct async_req *req, NTSTATUS status)
 {
        async_req_error(req, NT_STATUS_V(status));
@@ -62,13 +36,27 @@ bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev,
 
 bool async_req_is_nterror(struct async_req *req, NTSTATUS *status)
 {
-       uint32_t error = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR);
+       enum async_req_state state;
+       uint64_t error;
 
-       if (async_req_is_error(req, &error)) {
+       if (!async_req_is_error(req, &state, &error)) {
+               return false;
+       }
+       switch (state) {
+       case ASYNC_REQ_USER_ERROR:
                *status = NT_STATUS(error);
-               return true;
+               break;
+       case ASYNC_REQ_TIMED_OUT:
+               *status = NT_STATUS_IO_TIMEOUT;
+               break;
+       case ASYNC_REQ_NO_MEMORY:
+               *status = NT_STATUS_NO_MEMORY;
+               break;
+       default:
+               *status = NT_STATUS_INTERNAL_ERROR;
+               break;
        }
-       return false;
+       return true;
 }
 
 NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req)
index 7cc8caa..7555aac 100644 (file)
@@ -32,6 +32,4 @@ bool async_req_is_nterror(struct async_req *req, NTSTATUS *status);
 
 NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req);
 
-bool async_req_ntnomem(const void *p, struct async_req *req);
-
 #endif
index bafcdc5..78431d9 100644 (file)
@@ -1077,7 +1077,7 @@ static void open_socket_out_connected(struct async_req *subreq)
                subreq = async_connect_send(state, state->ev, state->fd,
                                            (struct sockaddr *)&state->ss,
                                            state->salen);
-               if (async_req_ntnomem(subreq, req)) {
+               if (async_req_nomem(subreq, req)) {
                        return;
                }
                if (!async_req_set_timeout(subreq, state->ev,
@@ -1209,7 +1209,7 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
 
        subreq = open_socket_out_send(state, state->ev, &state->ss,
                                      state->port, state->timeout);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = open_socket_out_defer_connected;
index 7bca627..e779e47 100644 (file)
@@ -96,7 +96,7 @@ static void wb_req_read_len(struct async_req *subreq)
        subreq = recvall_send(
                req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
                sizeof(struct winbindd_request) - sizeof(uint32), 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -135,7 +135,7 @@ static void wb_req_read_main(struct async_req *subreq)
 
        state->wb_req->extra_data.data = TALLOC_ARRAY(
                state->wb_req, char, state->wb_req->extra_len + 1);
-       if (async_req_ntnomem(state->wb_req->extra_data.data, req)) {
+       if (async_req_nomem(state->wb_req->extra_data.data, req)) {
                return;
        }
 
@@ -144,7 +144,7 @@ static void wb_req_read_main(struct async_req *subreq)
        subreq = recvall_send(
                req, state->ev, state->fd, state->wb_req->extra_data.data,
                state->wb_req->extra_len, 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -244,7 +244,7 @@ static void wb_req_write_main(struct async_req *subreq)
        subreq = sendall_send(state, state->ev, state->fd,
                              state->wb_req->extra_data.data,
                              state->wb_req->extra_len, 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -343,7 +343,7 @@ static void wb_resp_read_len(struct async_req *subreq)
        subreq = recvall_send(
                req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1,
                sizeof(struct winbindd_response) - sizeof(uint32), 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -375,7 +375,7 @@ static void wb_resp_read_main(struct async_req *subreq)
 
        state->wb_resp->extra_data.data = TALLOC_ARRAY(
                state->wb_resp, char, extra_len+1);
-       if (async_req_ntnomem(state->wb_resp->extra_data.data, req)) {
+       if (async_req_nomem(state->wb_resp->extra_data.data, req)) {
                return;
        }
        ((char *)state->wb_resp->extra_data.data)[extra_len] = 0;
@@ -383,7 +383,7 @@ static void wb_resp_read_main(struct async_req *subreq)
        subreq = recvall_send(
                req, state->ev, state->fd, state->wb_resp->extra_data.data,
                extra_len, 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -484,7 +484,7 @@ static void wb_resp_write_main(struct async_req *subreq)
                state, state->ev, state->fd,
                state->wb_resp->extra_data.data,
                state->wb_resp->length - sizeof(struct winbindd_response), 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
index cf5ce7e..f22b96a 100644 (file)
@@ -463,7 +463,7 @@ static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
 
        subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
                                   &state->wb_req);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -496,7 +496,7 @@ static void wb_open_pipe_ping_done(struct async_req *subreq)
 
        subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
                                   &state->wb_req);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -526,7 +526,7 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq)
        subreq = wb_connect_send(state, state->ev, state->wb_ctx,
                                 (char *)wb_resp->extra_data.data);
        TALLOC_FREE(wb_resp);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
@@ -582,7 +582,7 @@ static void wb_trigger_trans(struct async_req *req)
 
                subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
                                           state->need_priv);
-               if (async_req_ntnomem(subreq, req)) {
+               if (async_req_nomem(subreq, req)) {
                        return;
                }
                subreq->async.fn = wb_trans_connect_done;
@@ -592,7 +592,7 @@ static void wb_trigger_trans(struct async_req *req)
 
        subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
                                   state->wb_req);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = wb_trans_done;
@@ -665,7 +665,7 @@ static bool wb_trans_retry(struct async_req *req,
        }
 
        subreq = async_wait_send(state, state->ev, timeval_set(1, 0));
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return true;
        }
 
@@ -691,7 +691,7 @@ static void wb_trans_retry_wait_done(struct async_req *subreq)
 
        subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
                                   state->need_priv);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = wb_trans_connect_done;
@@ -715,7 +715,7 @@ static void wb_trans_connect_done(struct async_req *subreq)
 
        subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
                                   state->wb_req);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
 
index 26fa614..9d17ff8 100644 (file)
@@ -432,7 +432,7 @@ static void cli_pull_read_done(struct async_req *read_req)
                                state->start_offset + state->requested,
                                request_thistime);
 
-                       if (async_req_ntnomem(new_req, state->req)) {
+                       if (async_req_nomem(new_req, state->req)) {
                                return;
                        }
 
index b9fd322..2841ff0 100644 (file)
@@ -269,7 +269,7 @@ static void rpc_read_done(struct async_req *subreq)
                                             state->data + state->num_read,
                                             state->size - state->num_read,
                                             state->transport->priv);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = rpc_read_done;
@@ -350,7 +350,7 @@ static void rpc_write_done(struct async_req *subreq)
                                              state->data + state->num_written,
                                              state->size - state->num_written,
                                              state->transport->priv);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = rpc_write_done;
@@ -512,7 +512,7 @@ static void get_complete_frag_got_header(struct async_req *subreq)
                state, state->ev, state->cli->transport,
                (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
                state->prhdr->frag_len - RPC_HEADER_LEN);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = get_complete_frag_got_rest;
@@ -1138,7 +1138,7 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
        }
 
        state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
-       if (async_req_ntnomem(state->rdata, req)) {
+       if (async_req_nomem(state->rdata, req)) {
                return;
        }
 
@@ -1150,7 +1150,7 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
        subreq = state->transport->read_send(state, state->ev, state->rdata,
                                             RPC_HEADER_LEN,
                                             state->transport->priv);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = cli_api_pipe_read_done;
@@ -1336,7 +1336,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
         */
        rdata_copy = (char *)memdup(rdata, rdata_len);
        TALLOC_FREE(rdata);
-       if (async_req_ntnomem(rdata_copy, req)) {
+       if (async_req_nomem(rdata_copy, req)) {
                return;
        }
        prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
@@ -1344,7 +1344,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
        /* Ensure we have enough data for a pdu. */
        subreq = get_complete_frag_send(state, state->ev, state->cli,
                                        &state->rhdr, &state->incoming_frag);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = rpc_api_pipe_got_pdu;
@@ -1436,7 +1436,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
 
        subreq = get_complete_frag_send(state, state->ev, state->cli,
                                        &state->rhdr, &state->incoming_frag);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = rpc_api_pipe_got_pdu;
@@ -2235,7 +2235,7 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
                subreq = rpc_api_pipe_send(state, state->ev, state->cli,
                                           &state->outgoing_frag,
                                           RPC_RESPONSE);
-               if (async_req_ntnomem(subreq, req)) {
+               if (async_req_nomem(subreq, req)) {
                        return;
                }
                subreq->async.fn = rpc_api_pipe_req_done;
@@ -2246,7 +2246,7 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
                        state->cli->transport,
                        (uint8_t *)prs_data_p(&state->outgoing_frag),
                        prs_offset(&state->outgoing_frag));
-               if (async_req_ntnomem(subreq, req)) {
+               if (async_req_nomem(subreq, req)) {
                        return;
                }
                subreq->async.fn = rpc_api_pipe_req_write_done;
index b93e4cf..bf4aa65 100644 (file)
@@ -174,7 +174,7 @@ static void get_anon_ipc_negprot_done(struct async_req *subreq)
        }
 
        subreq = cli_session_setup_guest_send(state, state->ev, state->cli);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = get_anon_ipc_sesssetup_done;
@@ -198,7 +198,7 @@ static void get_anon_ipc_sesssetup_done(struct async_req *subreq)
 
        subreq = cli_tcon_andx_send(state, state->ev, state->cli,
                                    "IPC$", "IPC", NULL, 0);
-       if (async_req_ntnomem(subreq, req)) {
+       if (async_req_nomem(subreq, req)) {
                return;
        }
        subreq->async.fn = get_anon_ipc_tcon_done;