aboutsummaryrefslogtreecommitdiff
path: root/src/core/aio.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2023-11-25 17:35:35 -0800
committerGarrett D'Amore <garrett@damore.org>2023-11-25 17:47:02 -0800
commite623dedab28a1fec6270c05f9643e68bfb98b7c3 (patch)
tree2860475e583380771ac900c0d6417627efdcbd03 /src/core/aio.c
parente5fcc317c5f75d8fc6ea053c9f960e35e09ac38f (diff)
downloadnng-e623dedab28a1fec6270c05f9643e68bfb98b7c3.tar.gz
nng-e623dedab28a1fec6270c05f9643e68bfb98b7c3.tar.bz2
nng-e623dedab28a1fec6270c05f9643e68bfb98b7c3.zip
fixes #1523 rare SEGV in sub nni_list_remove
Credit goes to Wu Xuan (@willwu1217) for diagnosing and proposing a fix as part of #1695. This approach takes a revised approach to avoid adding extra memory, and it also is slightly faster as we do not need to update both pointers in the linked list, by reusing the reap node. As part of this a new internal API, nni_aio_completions, is introduced. In all likelihood we will be able to use this to solve some similar crashes in other areas of the code.
Diffstat (limited to 'src/core/aio.c')
-rw-r--r--src/core/aio.c33
1 files changed, 33 insertions, 0 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)
{