diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-16 16:27:22 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-16 16:27:22 -0800 |
| commit | ac8415c24ffea645105c3859e814843e81c97f8a (patch) | |
| tree | 7b64b4aab3de6ce5bdd69c3d5b7ead57f4a4b4e7 /src/core/event.c | |
| parent | b8f7236aa2928d70d9bff2e1071654982539eeda (diff) | |
| download | nng-ac8415c24ffea645105c3859e814843e81c97f8a.tar.gz nng-ac8415c24ffea645105c3859e814843e81c97f8a.tar.bz2 nng-ac8415c24ffea645105c3859e814843e81c97f8a.zip | |
Start of event framework.
This compiles correctly, but doesn't actually deliver events yet.
As part of this, I've made most of the initializables in nng
safe to tear-down if uninitialized (or set to zero e.g. via calloc).
This makes it loads easier to write the teardown on error code, since
I can deinit everything, without worrying about which things have been
initialized and which have not.
Diffstat (limited to 'src/core/event.c')
| -rw-r--r-- | src/core/event.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/core/event.c b/src/core/event.c new file mode 100644 index 00000000..3f7d1143 --- /dev/null +++ b/src/core/event.c @@ -0,0 +1,103 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include "core/nng_impl.h" + +#include <stdlib.h> +#include <string.h> + +int +nni_event_init(nni_event *event, int type, nni_sock *sock) +{ + int rv; + + memset(event, 0, sizeof (*event)); + if ((rv = nni_cv_init(&event->e_cv, &sock->s_mx)) != 0) { + return (rv); + } + NNI_LIST_NODE_INIT(&event->e_node); + event->e_type = type; + event->e_sock = sock; + return (0); +} + + +void +nni_event_fini(nni_event *event) +{ + nni_cv_fini(&event->e_cv); +} + + +void +nni_event_submit(nni_sock *sock, nni_event *event) +{ + // Call with socket mutex owned! + if (event->e_pending == 0) { + event->e_pending = 1; + event->e_done = 0; + nni_list_append(&sock->s_events, event); + nni_cv_wake(&sock->s_notify_cv); + } +} + + +void +nni_event_wait(nni_sock *sock, nni_event *event) +{ + // Call with socket mutex owned! + // Note that the socket mutex is dropped during the call. + while ((event->e_pending) && (!event->e_done)) { + nni_cv_wait(&event->e_cv); + } +} + + +void +nni_event_notifier(void *arg) +{ + nni_sock *sock = arg; + nni_event *event; + nni_notify *notify; + + nni_mtx_lock(&sock->s_mx); + for (;;) { + if (sock->s_closing) { + break; + } + + if ((event = nni_list_first(&sock->s_events)) != NULL) { + event->e_pending = 0; + nni_list_remove(&sock->s_events, event); + nni_mtx_unlock(&sock->s_mx); + + // Lock the notify list, it must not change. + nni_mtx_lock(&sock->s_notify_mx); + NNI_LIST_FOREACH (&sock->s_notify, notify) { + if ((notify->n_mask & event->e_type) == 0) { + // No interest. + continue; + } + notify->n_func(event, ¬ify->n_arg); + } + nni_mtx_unlock(&sock->s_notify_mx); + + nni_mtx_lock(&sock->s_mx); + // Let the event submitter know we are done, unless + // they have resubmitted. Submitters can wait on this + // lock. + event->e_done = 1; + nni_cv_wake(&event->e_cv); + continue; + } + + nni_cv_wait(&sock->s_notify_cv); + } + nni_mtx_unlock(&sock->s_mx); +} |
