}
}
-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;
}
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,
}
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);
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);
}