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
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);
}
/**
}
}
+/**
+ * @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
*/
bool async_post_error(struct async_req *req, struct tevent_context *ev,
- uint32_t error)
+ uint64_t error)
{
req->error = error;
- if (tevent_add_timer(ev, req, timeval_zero(),
+ if (tevent_add_timer(ev, req, tevent_timeval_zero(),
async_trigger, req) == NULL) {
return false;
}
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;
-}
-
-static void async_req_timedout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval now,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- TALLOC_FREE(te);
- async_req_nterror(req, NT_STATUS_IO_TIMEOUT);
-}
-
-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)
- != NULL);
-}
-
-struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct timeval to)
-{
- struct async_req *result;
-
- result = async_req_new(mem_ctx);
- if (result == NULL) {
- return result;
}
- if (!async_req_set_timeout(result, ev, to)) {
- TALLOC_FREE(result);
- return NULL;
- }
- return result;
-}
-
-bool async_wait_recv(struct async_req *req)
-{
+ *state = req->state;
return true;
}
if (!busy) {
struct tevent_timer *te;
- te = tevent_add_timer(ev, e, timeval_zero(),
+ te = tevent_add_timer(ev, e, tevent_timeval_zero(),
async_req_immediate_trigger,
e);
if (te == NULL) {