aboutsummaryrefslogtreecommitdiff
path: root/src/core/aio.h
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-09-01 10:26:34 -0700
committerGarrett D'Amore <garrett@damore.org>2017-09-22 11:48:10 -0700
commit2c977c35d8e44ad21345c3e91088f4f3d3f03605 (patch)
tree29722c23cadc1bb60ba035c717b41acf287eb90c /src/core/aio.h
parentd72076207a2fad96ff014a81366868fb47a0ed1b (diff)
downloadnng-2c977c35d8e44ad21345c3e91088f4f3d3f03605.tar.gz
nng-2c977c35d8e44ad21345c3e91088f4f3d3f03605.tar.bz2
nng-2c977c35d8e44ad21345c3e91088f4f3d3f03605.zip
Add support for synchronous AIO completions.
We add a flag (auto-clearing) that can be set on an AIO to indicate that the AIO should not processed asynchronously on a taskq. This can be used to enhance performance in some cases, but it can also be used to permit an AIO be destroyed from a completion callback. (For the latter, the callback must execute the new nni_aio_fini_cb() routine, which destroys the AIO without waiting for it to finish.)
Diffstat (limited to 'src/core/aio.h')
-rw-r--r--src/core/aio.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/core/aio.h b/src/core/aio.h
index eae17446..717e7995 100644
--- a/src/core/aio.h
+++ b/src/core/aio.h
@@ -35,7 +35,8 @@ struct nni_aio {
unsigned a_active : 1; // aio was started
unsigned a_expiring : 1; // expiration callback in progress
unsigned a_waiting : 1; // a thread is waiting for this to finish
- unsigned a_pad : 26; // ensure 32-bit alignment
+ unsigned a_synch : 1; // run completion synchronously
+ unsigned a_pad : 25; // ensure 32-bit alignment
nni_task a_task;
// Read/write operations.
@@ -76,6 +77,12 @@ extern int nni_aio_init(nni_aio **, nni_cb, void *);
// on zero'd memory.
extern void nni_aio_fini(nni_aio *);
+// nni_aio_fini_cb finalizes the aio WITHOUT waiting for it to complete.
+// This is intended exclusively for finalizing an AIO from a completion
+// callack for that AIO. It is important that the caller ensure that nothing
+// else might be waiting for that AIO or using it.
+extern void nni_aio_fini_cb(nni_aio *);
+
// nni_aio_stop cancels any unfinished I/O, running completion callbacks,
// but also prevents any new operations from starting (nni_aio_start will
// return NNG_ESTATE). This should be called before nni_aio_fini(). The
@@ -102,6 +109,19 @@ extern void * nni_aio_get_pipe(nni_aio *);
extern void nni_aio_set_ep(nni_aio *, void *);
extern void * nni_aio_get_ep(nni_aio *);
+// nni_aio_set_synch sets a synchronous completion flag on the AIO.
+// When this is set, the next time the AIO is completed, the callback
+// be run synchronously, from the thread calling the finish routine.
+// It is important that this only be set when the provider knows that
+// it is not holding any locks or resources when completing the operation,
+// or when the consumer knows that the callback routine does not acquire
+// any locks. Use with caution to avoid deadlocks. The flag is cleared
+// automatically when the completion callback is executed. Some care has
+// been taken so that other aio operations like aio_wait will work,
+// although it is still an error to try waiting for an aio from that aio's
+// completion callback.
+void nni_aio_set_synch(nni_aio *);
+
// nni_aio_set_timeout sets the timeout (absolute) when the AIO will
// be canceled. The cancelation does not happen until after nni_aio_start
// is called.