1 //
2 // Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
3 //
4 // This software is supplied under the terms of the MIT License, a
5 // copy of which should be located in the distribution where this
6 // file was obtained (LICENSE.txt). A copy of the license may also be
7 // found online at https://opensource.org/licenses/MIT.
8 //
9
10 #include "core/nng_impl.h"
11
12 void
nni_mtx_init(nni_mtx * mtx)13 nni_mtx_init(nni_mtx *mtx)
14 {
15 nni_plat_mtx_init(mtx);
16 }
17
18 void
nni_mtx_fini(nni_mtx * mtx)19 nni_mtx_fini(nni_mtx *mtx)
20 {
21 nni_plat_mtx_fini(mtx);
22 }
23
24 void
nni_mtx_lock(nni_mtx * mtx)25 nni_mtx_lock(nni_mtx *mtx)
26 {
27 nni_plat_mtx_lock(mtx);
28 }
29
30 void
nni_mtx_unlock(nni_mtx * mtx)31 nni_mtx_unlock(nni_mtx *mtx)
32 {
33 nni_plat_mtx_unlock(mtx);
34 }
35
36 void
nni_cv_init(nni_cv * cv,nni_mtx * mtx)37 nni_cv_init(nni_cv *cv, nni_mtx *mtx)
38 {
39 nni_plat_cv_init(cv, mtx);
40 }
41
42 void
nni_cv_fini(nni_cv * cv)43 nni_cv_fini(nni_cv *cv)
44 {
45 nni_plat_cv_fini(cv);
46 }
47
48 void
nni_cv_wait(nni_cv * cv)49 nni_cv_wait(nni_cv *cv)
50 {
51 nni_plat_cv_wait(cv);
52 }
53
54 int
nni_cv_until(nni_cv * cv,nni_time until)55 nni_cv_until(nni_cv *cv, nni_time until)
56 {
57 // Some special cases for times. Catching these here means that
58 // platforms can assume a valid time is presented to them.
59 if (until == NNI_TIME_NEVER) {
60 nni_plat_cv_wait(cv);
61 return (0);
62 }
63 if (until == NNI_TIME_ZERO) {
64 return (NNG_EAGAIN);
65 }
66
67 return (nni_plat_cv_until(cv, until));
68 }
69
70 void
nni_cv_wake(nni_cv * cv)71 nni_cv_wake(nni_cv *cv)
72 {
73 nni_plat_cv_wake(cv);
74 }
75
76 void
nni_cv_wake1(nni_cv * cv)77 nni_cv_wake1(nni_cv *cv)
78 {
79 nni_plat_cv_wake1(cv);
80 }
81
82 static void
nni_thr_wrap(void * arg)83 nni_thr_wrap(void *arg)
84 {
85 nni_thr *thr = arg;
86 int start;
87
88 nni_plat_mtx_lock(&thr->mtx);
89 while (((start = thr->start) == 0) && (thr->stop == 0)) {
90 nni_plat_cv_wait(&thr->cv);
91 }
92 nni_plat_mtx_unlock(&thr->mtx);
93 if ((start) && (thr->fn != NULL)) {
94 thr->fn(thr->arg);
95 }
96 nni_plat_mtx_lock(&thr->mtx);
97 thr->done = 1;
98 nni_plat_cv_wake(&thr->cv);
99 nni_plat_mtx_unlock(&thr->mtx);
100 }
101
102 int
nni_thr_init(nni_thr * thr,nni_thr_func fn,void * arg)103 nni_thr_init(nni_thr *thr, nni_thr_func fn, void *arg)
104 {
105 int rv;
106
107 thr->done = 0;
108 thr->start = 0;
109 thr->stop = 0;
110 thr->fn = fn;
111 thr->arg = arg;
112
113 nni_plat_mtx_init(&thr->mtx);
114 nni_plat_cv_init(&thr->cv, &thr->mtx);
115
116 if (fn == NULL) {
117 thr->init = 1;
118 thr->done = 1;
119 return (0);
120 }
121 if ((rv = nni_plat_thr_init(&thr->thr, nni_thr_wrap, thr)) != 0) {
122 thr->done = 1;
123 nni_plat_cv_fini(&thr->cv);
124 nni_plat_mtx_fini(&thr->mtx);
125 return (rv);
126 }
127 thr->init = 1;
128 return (0);
129 }
130
131 void
nni_thr_run(nni_thr * thr)132 nni_thr_run(nni_thr *thr)
133 {
134 nni_plat_mtx_lock(&thr->mtx);
135 thr->start = 1;
136 nni_plat_cv_wake(&thr->cv);
137 nni_plat_mtx_unlock(&thr->mtx);
138 }
139
140 void
nni_thr_fini(nni_thr * thr)141 nni_thr_fini(nni_thr *thr)
142 {
143 if (!thr->init) {
144 return;
145 }
146 nni_plat_mtx_lock(&thr->mtx);
147 thr->stop = 1;
148 nni_plat_cv_wake(&thr->cv);
149 while (!thr->done) {
150 nni_plat_cv_wait(&thr->cv);
151 }
152 nni_plat_mtx_unlock(&thr->mtx);
153 if (thr->fn != NULL) {
154 nni_plat_thr_fini(&thr->thr);
155 }
156
157 nni_plat_cv_fini(&thr->cv);
158 nni_plat_mtx_fini(&thr->mtx);
159 thr->init = 0;
160 }
161
162 bool
nni_thr_is_self(nni_thr * thr)163 nni_thr_is_self(nni_thr *thr)
164 {
165 if (!thr->init) {
166 return (false);
167 }
168 return (nni_plat_thr_is_self(&thr->thr));
169 }
170
171 void
nni_thr_set_name(nni_thr * thr,const char * name)172 nni_thr_set_name(nni_thr *thr, const char *name)
173 {
174 nni_plat_thr_set_name(thr != NULL ? &thr->thr : NULL, name);
175 }