//
|
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
//
|
// 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"
|
|
void
|
nni_mtx_init(nni_mtx *mtx)
|
{
|
nni_plat_mtx_init(mtx);
|
}
|
|
void
|
nni_mtx_fini(nni_mtx *mtx)
|
{
|
nni_plat_mtx_fini(mtx);
|
}
|
|
void
|
nni_mtx_lock(nni_mtx *mtx)
|
{
|
nni_plat_mtx_lock(mtx);
|
}
|
|
void
|
nni_mtx_unlock(nni_mtx *mtx)
|
{
|
nni_plat_mtx_unlock(mtx);
|
}
|
|
void
|
nni_cv_init(nni_cv *cv, nni_mtx *mtx)
|
{
|
nni_plat_cv_init(cv, mtx);
|
}
|
|
void
|
nni_cv_fini(nni_cv *cv)
|
{
|
nni_plat_cv_fini(cv);
|
}
|
|
void
|
nni_cv_wait(nni_cv *cv)
|
{
|
nni_plat_cv_wait(cv);
|
}
|
|
int
|
nni_cv_until(nni_cv *cv, nni_time until)
|
{
|
// Some special cases for times. Catching these here means that
|
// platforms can assume a valid time is presented to them.
|
if (until == NNI_TIME_NEVER) {
|
nni_plat_cv_wait(cv);
|
return (0);
|
}
|
if (until == NNI_TIME_ZERO) {
|
return (NNG_EAGAIN);
|
}
|
|
return (nni_plat_cv_until(cv, until));
|
}
|
|
void
|
nni_cv_wake(nni_cv *cv)
|
{
|
nni_plat_cv_wake(cv);
|
}
|
|
void
|
nni_cv_wake1(nni_cv *cv)
|
{
|
nni_plat_cv_wake1(cv);
|
}
|
|
static void
|
nni_thr_wrap(void *arg)
|
{
|
nni_thr *thr = arg;
|
int start;
|
|
nni_plat_mtx_lock(&thr->mtx);
|
while (((start = thr->start) == 0) && (thr->stop == 0)) {
|
nni_plat_cv_wait(&thr->cv);
|
}
|
nni_plat_mtx_unlock(&thr->mtx);
|
if ((start) && (thr->fn != NULL)) {
|
thr->fn(thr->arg);
|
}
|
nni_plat_mtx_lock(&thr->mtx);
|
thr->done = 1;
|
nni_plat_cv_wake(&thr->cv);
|
nni_plat_mtx_unlock(&thr->mtx);
|
}
|
|
int
|
nni_thr_init(nni_thr *thr, nni_thr_func fn, void *arg)
|
{
|
int rv;
|
|
thr->done = 0;
|
thr->start = 0;
|
thr->stop = 0;
|
thr->fn = fn;
|
thr->arg = arg;
|
|
nni_plat_mtx_init(&thr->mtx);
|
nni_plat_cv_init(&thr->cv, &thr->mtx);
|
|
if (fn == NULL) {
|
thr->init = 1;
|
thr->done = 1;
|
return (0);
|
}
|
if ((rv = nni_plat_thr_init(&thr->thr, nni_thr_wrap, thr)) != 0) {
|
thr->done = 1;
|
nni_plat_cv_fini(&thr->cv);
|
nni_plat_mtx_fini(&thr->mtx);
|
return (rv);
|
}
|
thr->init = 1;
|
return (0);
|
}
|
|
void
|
nni_thr_run(nni_thr *thr)
|
{
|
nni_plat_mtx_lock(&thr->mtx);
|
thr->start = 1;
|
nni_plat_cv_wake(&thr->cv);
|
nni_plat_mtx_unlock(&thr->mtx);
|
}
|
|
void
|
nni_thr_fini(nni_thr *thr)
|
{
|
if (!thr->init) {
|
return;
|
}
|
nni_plat_mtx_lock(&thr->mtx);
|
thr->stop = 1;
|
nni_plat_cv_wake(&thr->cv);
|
while (!thr->done) {
|
nni_plat_cv_wait(&thr->cv);
|
}
|
nni_plat_mtx_unlock(&thr->mtx);
|
if (thr->fn != NULL) {
|
nni_plat_thr_fini(&thr->thr);
|
}
|
|
nni_plat_cv_fini(&thr->cv);
|
nni_plat_mtx_fini(&thr->mtx);
|
thr->init = 0;
|
}
|
|
bool
|
nni_thr_is_self(nni_thr *thr)
|
{
|
if (!thr->init) {
|
return (false);
|
}
|
return (nni_plat_thr_is_self(&thr->thr));
|
}
|
|
void
|
nni_thr_set_name(nni_thr *thr, const char *name)
|
{
|
nni_plat_thr_set_name(thr != NULL ? &thr->thr : NULL, name);
|
}
|