/src/CMake/Utilities/cmlibuv/src/unix/loop.c
Line | Count | Source |
1 | | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | | * |
3 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | | * of this software and associated documentation files (the "Software"), to |
5 | | * deal in the Software without restriction, including without limitation the |
6 | | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | | * sell copies of the Software, and to permit persons to whom the Software is |
8 | | * furnished to do so, subject to the following conditions: |
9 | | * |
10 | | * The above copyright notice and this permission notice shall be included in |
11 | | * all copies or substantial portions of the Software. |
12 | | * |
13 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | | * IN THE SOFTWARE. |
20 | | */ |
21 | | |
22 | | #include "uv.h" |
23 | | #include "uv/tree.h" |
24 | | #include "internal.h" |
25 | | #include "heap-inl.h" |
26 | | #include <stdlib.h> |
27 | | #include <string.h> |
28 | | #include <unistd.h> |
29 | | |
30 | 0 | int uv_loop_init(uv_loop_t* loop) { |
31 | 0 | uv__loop_internal_fields_t* lfields; |
32 | 0 | void* saved_data; |
33 | 0 | int err; |
34 | |
|
35 | 0 | saved_data = loop->data; |
36 | 0 | memset(loop, 0, sizeof(*loop)); |
37 | 0 | loop->data = saved_data; |
38 | |
|
39 | 0 | lfields = uv__calloc(1, sizeof(*lfields)); |
40 | 0 | if (lfields == NULL) |
41 | 0 | return UV_ENOMEM; |
42 | 0 | loop->internal_fields = lfields; |
43 | |
|
44 | 0 | err = uv_mutex_init(&lfields->loop_metrics.lock); |
45 | 0 | if (err) |
46 | 0 | goto fail_metrics_mutex_init; |
47 | 0 | memset(&lfields->loop_metrics.metrics, |
48 | 0 | 0, |
49 | 0 | sizeof(lfields->loop_metrics.metrics)); |
50 | |
|
51 | 0 | heap_init((struct heap*) &loop->timer_heap); |
52 | 0 | uv__queue_init(&loop->wq); |
53 | 0 | uv__queue_init(&loop->idle_handles); |
54 | 0 | uv__queue_init(&loop->async_handles); |
55 | 0 | uv__queue_init(&loop->check_handles); |
56 | 0 | uv__queue_init(&loop->prepare_handles); |
57 | 0 | uv__queue_init(&loop->handle_queue); |
58 | |
|
59 | 0 | loop->active_handles = 0; |
60 | 0 | loop->active_reqs.count = 0; |
61 | 0 | loop->nfds = 0; |
62 | 0 | loop->watchers = NULL; |
63 | 0 | loop->nwatchers = 0; |
64 | 0 | uv__queue_init(&loop->pending_queue); |
65 | 0 | uv__queue_init(&loop->watcher_queue); |
66 | |
|
67 | 0 | loop->closing_handles = NULL; |
68 | 0 | uv__update_time(loop); |
69 | 0 | loop->async_io_watcher.fd = -1; |
70 | 0 | loop->async_wfd = -1; |
71 | 0 | loop->signal_pipefd[0] = -1; |
72 | 0 | loop->signal_pipefd[1] = -1; |
73 | 0 | loop->backend_fd = -1; |
74 | 0 | loop->emfile_fd = -1; |
75 | |
|
76 | 0 | loop->timer_counter = 0; |
77 | 0 | loop->stop_flag = 0; |
78 | |
|
79 | 0 | err = uv__platform_loop_init(loop); |
80 | 0 | if (err) |
81 | 0 | goto fail_platform_init; |
82 | | |
83 | 0 | uv__signal_global_once_init(); |
84 | 0 | err = uv__process_init(loop); |
85 | 0 | if (err) |
86 | 0 | goto fail_process_init; |
87 | 0 | uv__queue_init(&loop->process_handles); |
88 | |
|
89 | 0 | err = uv_rwlock_init(&loop->cloexec_lock); |
90 | 0 | if (err) |
91 | 0 | goto fail_rwlock_init; |
92 | | |
93 | 0 | err = uv_mutex_init(&loop->wq_mutex); |
94 | 0 | if (err) |
95 | 0 | goto fail_mutex_init; |
96 | | |
97 | 0 | err = uv_async_init(loop, &loop->wq_async, uv__work_done); |
98 | 0 | if (err) |
99 | 0 | goto fail_async_init; |
100 | | |
101 | 0 | uv__handle_unref(&loop->wq_async); |
102 | 0 | loop->wq_async.flags |= UV_HANDLE_INTERNAL; |
103 | |
|
104 | 0 | return 0; |
105 | | |
106 | 0 | fail_async_init: |
107 | 0 | uv_mutex_destroy(&loop->wq_mutex); |
108 | |
|
109 | 0 | fail_mutex_init: |
110 | 0 | uv_rwlock_destroy(&loop->cloexec_lock); |
111 | |
|
112 | 0 | fail_rwlock_init: |
113 | 0 | fail_process_init: |
114 | 0 | uv__signal_loop_cleanup(loop); |
115 | 0 | uv__platform_loop_delete(loop); |
116 | |
|
117 | 0 | if (loop->backend_fd != -1) { |
118 | 0 | uv__close(loop->backend_fd); |
119 | 0 | loop->backend_fd = -1; |
120 | 0 | } |
121 | |
|
122 | 0 | fail_platform_init: |
123 | 0 | uv_mutex_destroy(&lfields->loop_metrics.lock); |
124 | |
|
125 | 0 | fail_metrics_mutex_init: |
126 | 0 | uv__free(lfields); |
127 | 0 | loop->internal_fields = NULL; |
128 | |
|
129 | 0 | uv__free(loop->watchers); |
130 | 0 | loop->nwatchers = 0; |
131 | 0 | return err; |
132 | 0 | } |
133 | | |
134 | | |
135 | 0 | int uv_loop_fork(uv_loop_t* loop) { |
136 | 0 | int err; |
137 | 0 | unsigned int i; |
138 | 0 | uv__io_t* w; |
139 | |
|
140 | 0 | err = uv__io_fork(loop); |
141 | 0 | if (err) |
142 | 0 | return err; |
143 | | |
144 | 0 | err = uv__async_fork(loop); |
145 | 0 | if (err) |
146 | 0 | return err; |
147 | | |
148 | 0 | err = uv__signal_loop_fork(loop); |
149 | 0 | if (err) |
150 | 0 | return err; |
151 | | |
152 | | /* Rearm all the watchers that aren't re-queued by the above. */ |
153 | 0 | for (i = 0; i < loop->nwatchers; i++) { |
154 | 0 | w = loop->watchers[i]; |
155 | 0 | if (w == NULL) |
156 | 0 | continue; |
157 | | |
158 | 0 | if (w->pevents != 0 && uv__queue_empty(&w->watcher_queue)) { |
159 | 0 | w->events = 0; /* Force re-registration in uv__io_poll. */ |
160 | 0 | uv__queue_insert_tail(&loop->watcher_queue, &w->watcher_queue); |
161 | 0 | } |
162 | 0 | } |
163 | |
|
164 | 0 | return 0; |
165 | 0 | } |
166 | | |
167 | | |
168 | 0 | void uv__loop_close(uv_loop_t* loop) { |
169 | 0 | uv__loop_internal_fields_t* lfields; |
170 | |
|
171 | 0 | uv__signal_loop_cleanup(loop); |
172 | 0 | uv__platform_loop_delete(loop); |
173 | 0 | uv__async_stop(loop); |
174 | |
|
175 | 0 | if (loop->emfile_fd != -1) { |
176 | 0 | uv__close(loop->emfile_fd); |
177 | 0 | loop->emfile_fd = -1; |
178 | 0 | } |
179 | |
|
180 | 0 | if (loop->backend_fd != -1) { |
181 | 0 | uv__close(loop->backend_fd); |
182 | 0 | loop->backend_fd = -1; |
183 | 0 | } |
184 | |
|
185 | 0 | uv_mutex_lock(&loop->wq_mutex); |
186 | 0 | assert(uv__queue_empty(&loop->wq) && "thread pool work queue not empty!"); |
187 | 0 | assert(!uv__has_active_reqs(loop)); |
188 | 0 | uv_mutex_unlock(&loop->wq_mutex); |
189 | 0 | uv_mutex_destroy(&loop->wq_mutex); |
190 | | |
191 | | /* |
192 | | * Note that all thread pool stuff is finished at this point and |
193 | | * it is safe to just destroy rw lock |
194 | | */ |
195 | 0 | uv_rwlock_destroy(&loop->cloexec_lock); |
196 | |
|
197 | | #if 0 |
198 | | assert(uv__queue_empty(&loop->pending_queue)); |
199 | | assert(uv__queue_empty(&loop->watcher_queue)); |
200 | | assert(loop->nfds == 0); |
201 | | #endif |
202 | |
|
203 | 0 | uv__free(loop->watchers); |
204 | 0 | loop->watchers = NULL; |
205 | 0 | loop->nwatchers = 0; |
206 | |
|
207 | 0 | lfields = uv__get_internal_fields(loop); |
208 | 0 | uv_mutex_destroy(&lfields->loop_metrics.lock); |
209 | 0 | uv__free(lfields); |
210 | 0 | loop->internal_fields = NULL; |
211 | 0 | } |
212 | | |
213 | | |
214 | 0 | int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { |
215 | 0 | uv__loop_internal_fields_t* lfields; |
216 | |
|
217 | 0 | lfields = uv__get_internal_fields(loop); |
218 | 0 | if (option == UV_METRICS_IDLE_TIME) { |
219 | 0 | lfields->flags |= UV_METRICS_IDLE_TIME; |
220 | 0 | return 0; |
221 | 0 | } |
222 | | |
223 | 0 | #if defined(__linux__) |
224 | 0 | if (option == UV_LOOP_USE_IO_URING_SQPOLL) { |
225 | 0 | loop->flags |= UV_LOOP_ENABLE_IO_URING_SQPOLL; |
226 | 0 | return 0; |
227 | 0 | } |
228 | 0 | #endif |
229 | | |
230 | | |
231 | 0 | if (option != UV_LOOP_BLOCK_SIGNAL) |
232 | 0 | return UV_ENOSYS; |
233 | | |
234 | 0 | if (va_arg(ap, int) != SIGPROF) |
235 | 0 | return UV_EINVAL; |
236 | | |
237 | 0 | loop->flags |= UV_LOOP_BLOCK_SIGPROF; |
238 | 0 | return 0; |
239 | 0 | } |