diff options
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/lib/asys/asys.c | 49 | ||||
| -rw-r--r-- | source3/lib/asys/asys.h | 26 | ||||
| -rw-r--r-- | source3/lib/asys/tests.c | 14 | ||||
| -rw-r--r-- | source3/modules/vfs_default.c | 35 |
4 files changed, 69 insertions, 55 deletions
diff --git a/source3/lib/asys/asys.c b/source3/lib/asys/asys.c index 1fd7700f9b..906d8cf1c1 100644 --- a/source3/lib/asys/asys.c +++ b/source3/lib/asys/asys.c @@ -288,30 +288,41 @@ void asys_cancel(struct asys_context *ctx, void *private_data) } } -int asys_result(struct asys_context *ctx, ssize_t *pret, int *perrno, - void *pdata) +int asys_results(struct asys_context *ctx, struct asys_result *results, + unsigned num_results) { - void **pprivate_data = (void **)pdata; - struct asys_job *job; - int ret, jobid; + int jobids[num_results]; + int i, ret; - ret = pthreadpool_finished_jobs(ctx->pool, &jobid, 1); - if (ret < 0) { - return -ret; - } - if ((jobid < 0) || (jobid >= ctx->num_jobs)) { - return EIO; + ret = pthreadpool_finished_jobs(ctx->pool, jobids, num_results); + if (ret <= 0) { + return ret; } - job = ctx->jobs[jobid]; + for (i=0; i<ret; i++) { + struct asys_result *result = &results[i]; + struct asys_job *job; + int jobid; + + jobid = jobids[i]; + + if ((jobid < 0) || (jobid >= ctx->num_jobs)) { + return -EIO; + } + + job = ctx->jobs[jobid]; - if (job->canceled) { - return ECANCELED; + if (job->canceled) { + result->ret = -1; + result->err = ECANCELED; + } else { + result->ret = job->ret; + result->err = job->err; + } + result->private_data = job->private_data; + + job->busy = 0; } - *pret = job->ret; - *perrno = job->err; - *pprivate_data = job->private_data; - job->busy = 0; - return 0; + return ret; } diff --git a/source3/lib/asys/asys.h b/source3/lib/asys/asys.h index 10805bdd1f..7c3dfdfbaf 100644 --- a/source3/lib/asys/asys.h +++ b/source3/lib/asys/asys.h @@ -104,18 +104,28 @@ void asys_set_log_fn(struct asys_context *ctx, asys_log_fn fn, int asys_signalfd(struct asys_context *ctx); +struct asys_result { + ssize_t ret; + int err; + void *private_data; +}; + /** - * @brief Pull the result from an async operation + * @brief Pull the results from async operations * - * Whe the fd returned from asys_signalfd() is readable, an async - * operation has finished. The result from the async operation can be - * pulled with asys_result(). + * Whe the fd returned from asys_signalfd() is readable, one or more async + * operations have finished. The result from the async operations can be pulled + * with asys_results(). * - * @param[in] ctx The asys context - * @return success: 0, failure: errno + * @param[in] ctx The asys context + * @param[out] results The result strutcts + * @param[in] num_results The length of the results array + * @return success: >=0, number of finished jobs + * failure: -errno */ -int asys_result(struct asys_context *ctx, ssize_t *pret, int *perrno, - void *pdata); +int asys_results(struct asys_context *ctx, struct asys_result *results, + unsigned num_results); + void asys_cancel(struct asys_context *ctx, void *private_data); int asys_pread(struct asys_context *ctx, int fildes, void *buf, size_t nbyte, diff --git a/source3/lib/asys/tests.c b/source3/lib/asys/tests.c index 354f1bfbdb..e54e3ea2d2 100644 --- a/source3/lib/asys/tests.c +++ b/source3/lib/asys/tests.c @@ -64,20 +64,18 @@ int main(int argc, const char *argv[]) } for (i=0; i<ntasks; i++) { - void *priv; - ssize_t retval; - int err; + struct asys_result result; int *pidx; - ret = asys_result(ctx, &retval, &err, &priv); - if (ret == -1) { - errno = ret; + ret = asys_results(ctx, &result, 1); + if (ret < 0) { + errno = -ret; perror("asys_result failed"); return 1; } - pidx = (int *)priv; + pidx = (int *)result.private_data; - printf("%d returned %d\n", *pidx, (int)retval); + printf("%d returned %d\n", *pidx, (int)result.ret); } ret = asys_context_destroy(ctx); diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 7dd9c0ca3e..02ab35b128 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -793,44 +793,39 @@ static void vfswrap_asys_finished(struct tevent_context *ev, uint16_t flags, void *p) { struct asys_context *asys_ctx = (struct asys_context *)p; - struct tevent_req *req; - struct vfswrap_asys_state *state; - int res; - ssize_t ret; - int err; - void *private_data; if ((flags & TEVENT_FD_READ) == 0) { return; } while (true) { - res = asys_result(asys_ctx, &ret, &err, &private_data); - if (res == EINTR || res == EAGAIN) { + struct tevent_req *req; + struct vfswrap_asys_state *state; + struct asys_result result; + int res; + + res = asys_results(asys_ctx, &result, 1); + if (res < 0) { + DEBUG(1, ("asys_result returned %s\n", + strerror(-res))); return; } -#ifdef EWOULDBLOCK - if (res == EWOULDBLOCK) { - return; - } -#endif - - if (res == ECANCELED) { + if (res == 0) { return; } - if (res != 0) { - DEBUG(1, ("asys_result returned %s\n", strerror(res))); + if ((result.ret == -1) && (result.err == ECANCELED)) { return; } - req = talloc_get_type_abort(private_data, struct tevent_req); + req = talloc_get_type_abort(result.private_data, + struct tevent_req); state = tevent_req_data(req, struct vfswrap_asys_state); talloc_set_destructor(state, NULL); - state->ret = ret; - state->err = err; + state->ret = result.ret; + state->err = result.err; tevent_req_defer_callback(req, ev); tevent_req_done(req); } |
