summaryrefslogtreecommitdiff
path: root/source3/lib/asys
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-03-24 14:36:34 +0000
committerJeremy Allison <jra@samba.org>2014-03-27 06:06:12 +0100
commitc35fec883cf344a269e65670521e2580a91c24aa (patch)
tree17fbb77f4671ea8aaa94399de88471592ba6e436 /source3/lib/asys
parentc5d07df6abe657ff196266bbfbb376ca7db0968b (diff)
downloadsamba-c35fec883cf344a269e65670521e2580a91c24aa.tar.gz
asys: Allow multiple results to be received
This makes use of C99 dynamic arrays. In this performance-sensitive code, I would like to avoid malloc/free, and I think 15 years after the standard we might be able to use this feature. Alternatively, we could use the "results" memory area and store the jobids in the upper range, playing some cast-tricks. Should work as well. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/lib/asys')
-rw-r--r--source3/lib/asys/asys.c49
-rw-r--r--source3/lib/asys/asys.h26
-rw-r--r--source3/lib/asys/tests.c14
3 files changed, 54 insertions, 35 deletions
diff --git a/source3/lib/asys/asys.c b/source3/lib/asys/asys.c
index 1fd7700f9bf..906d8cf1c1e 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 10805bdd1fe..7c3dfdfbaf5 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 354f1bfbdb5..e54e3ea2d22 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);