aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/aio.c33
-rw-r--r--src/core/aio.h26
2 files changed, 58 insertions, 1 deletions
diff --git a/src/core/aio.c b/src/core/aio.c
index 564e91a3..e849b33d 100644
--- a/src/core/aio.c
+++ b/src/core/aio.c
@@ -508,6 +508,39 @@ nni_aio_list_active(nni_aio *aio)
return (nni_list_node_active(&aio->a_prov_node));
}
+// completions list.
+// Implementation note: in order to avoid wasting space, we
+// reuse the reap node -- which will be inactive here.
+void
+nni_aio_completions_init(nni_aio_completions *clp)
+{
+ *clp = NULL;
+}
+
+void
+nni_aio_completions_add(nni_aio_completions *clp, nni_aio *aio, int result, size_t count)
+{
+ NNI_ASSERT(!nni_aio_list_active(aio));
+ aio->a_reap_node.rn_next = *clp;
+ aio->a_result = result;
+ aio->a_count = count;
+ *clp = aio;
+}
+
+void
+nni_aio_completions_run(nni_aio_completions *clp)
+{
+ nni_aio *aio;
+ nni_aio *cl = *clp;
+ *clp = NULL;
+
+ while ((aio = cl) != NULL) {
+ cl = (void *)aio->a_reap_node.rn_next;
+ aio->a_reap_node.rn_next = NULL;
+ nni_aio_finish_sync(aio, aio->a_result, aio->a_count);
+ }
+}
+
static void
nni_aio_expire_add(nni_aio *aio)
{
diff --git a/src/core/aio.h b/src/core/aio.h
index 6315e90c..a2ebf70a 100644
--- a/src/core/aio.h
+++ b/src/core/aio.h
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -166,6 +166,30 @@ extern int nni_aio_schedule(nni_aio *, nni_aio_cancel_fn, void *);
extern void nni_sleep_aio(nni_duration, nni_aio *);
+// nni_aio_completion_list is used after removing the aio from an
+// active work queue, and keeping them so that the completions can
+// be run in a deferred manner. These lists are simple, and intended
+// to be used as local variables. It's important to initialize the
+// list before using it. Also, any AIO added to a completion list must
+// not be in active use anywhere.
+typedef void *nni_aio_completions;
+
+// nni_aio_completions_init just initializes a completions list.
+// This just sets the pointed value to NULL.
+extern void nni_aio_completions_init(nni_aio_completions *);
+
+// nni_aio_completions_run runs nni_aio_finish_sync for all the aio objects
+// that have been added to the completions. The result code and count used
+// are those supplied in nni_aio_completions_add. Callers should not hold
+// locks when calling this.
+extern void nni_aio_completions_run(nni_aio_completions *);
+
+// nni_aio_completions_add adds an aio (with the result code and length as
+// appropriate) to the completion list. This should be done while the
+// appropriate lock is held. The aio must not be scheduled.
+extern void nni_aio_completions_add(nni_aio_completions *, nni_aio *,
+ int, size_t);
+
extern int nni_aio_sys_init(void);
extern void nni_aio_sys_fini(void);