• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  * Permission is hereby granted, free of charge, to any person obtaining a copy
3  * of this software and associated documentation files (the "Software"), to
4  * deal in the Software without restriction, including without limitation the
5  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6  * sell copies of the Software, and to permit persons to whom the Software is
7  * furnished to do so, subject to the following conditions:
8  *
9  * The above copyright notice and this permission notice shall be included in
10  * all copies or substantial portions of the Software.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18  * IN THE SOFTWARE.
19  */
20 
21 #include "uv.h"
22 #include "internal.h"
23 #include "uv_log.h"
24 #ifdef USE_FFRT
25 #include "ffrt_inner.h"
26 #endif
27 #include <assert.h>
28 #include <errno.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 #ifndef SA_RESTART
35 # define SA_RESTART 0
36 #endif
37 
38 typedef struct {
39   uv_signal_t* handle;
40   int signum;
41 } uv__signal_msg_t;
42 
43 RB_HEAD(uv__signal_tree_s, uv_signal_s);
44 
45 
46 static int uv__signal_unlock(void);
47 static int uv__signal_start(uv_signal_t* handle,
48                             uv_signal_cb signal_cb,
49                             int signum,
50                             int oneshot);
51 static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
52 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
53 static void uv__signal_stop(uv_signal_t* handle);
54 static void uv__signal_unregister_handler(int signum);
55 
56 
57 static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
58 static struct uv__signal_tree_s uv__signal_tree =
59     RB_INITIALIZER(uv__signal_tree);
60 static int uv__signal_lock_pipefd[2] = { -1, -1 };
61 
62 RB_GENERATE_STATIC(uv__signal_tree_s,
63                    uv_signal_s, tree_entry,
64                    uv__signal_compare)
65 
66 static void uv__signal_global_reinit(void);
67 
uv__signal_global_init(void)68 static void uv__signal_global_init(void) {
69   if (uv__signal_lock_pipefd[0] == -1)
70     /* pthread_atfork can register before and after handlers, one
71      * for each child. This only registers one for the child. That
72      * state is both persistent and cumulative, so if we keep doing
73      * it the handler functions will be called multiple times. Thus
74      * we only want to do it once.
75      */
76     if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
77       abort();
78 
79   uv__signal_global_reinit();
80 }
81 
82 
uv__signal_cleanup(void)83 void uv__signal_cleanup(void) {
84   /* We can only use signal-safe functions here.
85    * That includes read/write and close, fortunately.
86    * We do all of this directly here instead of resetting
87    * uv__signal_global_init_guard because
88    * uv__signal_global_once_init is only called from uv_loop_init
89    * and this needs to function in existing loops.
90    */
91   if (uv__signal_lock_pipefd[0] != -1) {
92     uv__close(uv__signal_lock_pipefd[0]);
93     uv__signal_lock_pipefd[0] = -1;
94   }
95 
96   if (uv__signal_lock_pipefd[1] != -1) {
97     uv__close(uv__signal_lock_pipefd[1]);
98     uv__signal_lock_pipefd[1] = -1;
99   }
100 }
101 
102 
uv__signal_global_reinit(void)103 static void uv__signal_global_reinit(void) {
104   uv__signal_cleanup();
105 
106   if (uv__make_pipe(uv__signal_lock_pipefd, 0))
107     abort();
108 
109   if (uv__signal_unlock()) {
110 #ifdef USE_OHOS_DFX
111     UV_LOGF("errno:%{public}d, sig_lock_pfd[1]:%{public}d", errno, uv__signal_lock_pipefd[1]);
112     return;
113 #else
114     abort();
115 #endif
116   }
117 }
118 
119 
uv__signal_global_once_init(void)120 void uv__signal_global_once_init(void) {
121   uv_once(&uv__signal_global_init_guard, uv__signal_global_init);
122 }
123 
124 
uv__signal_lock(void)125 static int uv__signal_lock(void) {
126   int r;
127   char data;
128 
129   do {
130     r = read(uv__signal_lock_pipefd[0], &data, sizeof data);
131   } while (r < 0 && errno == EINTR);
132 
133   return (r < 0) ? -1 : 0;
134 }
135 
136 
uv__signal_unlock(void)137 static int uv__signal_unlock(void) {
138   int r;
139   char data = 42;
140 
141   do {
142     r = write(uv__signal_lock_pipefd[1], &data, sizeof data);
143   } while (r < 0 && errno == EINTR);
144 
145   return (r < 0) ? -1 : 0;
146 }
147 
148 
uv__signal_block_and_lock(sigset_t * saved_sigmask)149 static void uv__signal_block_and_lock(sigset_t* saved_sigmask) {
150   sigset_t new_mask;
151 
152   if (sigfillset(&new_mask))
153     abort();
154 
155   /* to shut up valgrind */
156   sigemptyset(saved_sigmask);
157   if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask))
158     abort();
159 
160   if (uv__signal_lock()) {
161 #ifdef USE_OHOS_DFX
162     UV_LOGF("errno:%{public}d, sig_lock_pfd[0]:%{public}d", errno, uv__signal_lock_pipefd[0]);
163     return;
164 #else
165     abort();
166 #endif
167   }
168 }
169 
170 
uv__signal_unlock_and_unblock(sigset_t * saved_sigmask)171 static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) {
172   if (uv__signal_unlock()) {
173 #ifdef USE_OHOS_DFX
174     UV_LOGF("errno:%{public}d, sig_lock_pfd[1]:%{public}d", errno, uv__signal_lock_pipefd[1]);
175     return;
176 #else
177     abort();
178 #endif
179   }
180 
181   if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL))
182     abort();
183 }
184 
185 
uv__signal_first_handle(int signum)186 static uv_signal_t* uv__signal_first_handle(int signum) {
187   /* This function must be called with the signal lock held. */
188   uv_signal_t lookup;
189   uv_signal_t* handle;
190 
191   lookup.signum = signum;
192   lookup.flags = 0;
193   lookup.loop = NULL;
194 
195   handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
196 
197   if (handle != NULL && handle->signum == signum)
198     return handle;
199 
200   return NULL;
201 }
202 
203 
uv__signal_handler(int signum)204 static void uv__signal_handler(int signum) {
205   uv__signal_msg_t msg;
206   uv_signal_t* handle;
207   int saved_errno;
208 
209   saved_errno = errno;
210   memset(&msg, 0, sizeof msg);
211 
212   if (uv__signal_lock()) {
213     errno = saved_errno;
214     return;
215   }
216 
217   for (handle = uv__signal_first_handle(signum);
218        handle != NULL && handle->signum == signum;
219        handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
220     int r;
221 
222     msg.signum = signum;
223     msg.handle = handle;
224 
225     /* write() should be atomic for small data chunks, so the entire message
226      * should be written at once. In theory the pipe could become full, in
227      * which case the user is out of luck.
228      */
229     do {
230       r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
231     } while (r == -1 && errno == EINTR);
232 
233     assert(r == sizeof msg ||
234            (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));
235 
236     if (r != -1)
237       handle->caught_signals++;
238   }
239 
240   uv__signal_unlock();
241   errno = saved_errno;
242 }
243 
244 
uv__signal_register_handler(int signum,int oneshot)245 static int uv__signal_register_handler(int signum, int oneshot) {
246   /* When this function is called, the signal lock must be held. */
247   struct sigaction sa;
248 
249   /* XXX use a separate signal stack? */
250   memset(&sa, 0, sizeof(sa));
251   if (sigfillset(&sa.sa_mask))
252     abort();
253   sa.sa_handler = uv__signal_handler;
254   sa.sa_flags = SA_RESTART;
255   if (oneshot)
256     sa.sa_flags |= SA_RESETHAND;
257 
258   /* XXX save old action so we can restore it later on? */
259   if (sigaction(signum, &sa, NULL))
260     return UV__ERR(errno);
261 
262   return 0;
263 }
264 
265 
uv__signal_unregister_handler(int signum)266 static void uv__signal_unregister_handler(int signum) {
267   /* When this function is called, the signal lock must be held. */
268   struct sigaction sa;
269 
270   memset(&sa, 0, sizeof(sa));
271   sa.sa_handler = SIG_DFL;
272 
273   /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a
274    * signal implies that it was successfully registered earlier, so EINVAL
275    * should never happen.
276    */
277   if (sigaction(signum, &sa, NULL))
278     abort();
279 }
280 
281 
uv__signal_loop_once_init(uv_loop_t * loop)282 static int uv__signal_loop_once_init(uv_loop_t* loop) {
283   int err;
284 
285   /* Return if already initialized. */
286   if (loop->signal_pipefd[0] != -1)
287     return 0;
288 
289   err = uv__make_pipe(loop->signal_pipefd, UV_NONBLOCK_PIPE);
290   if (err)
291     return err;
292 
293   uv__io_init(&loop->signal_io_watcher,
294               uv__signal_event,
295               loop->signal_pipefd[0]);
296   uv__io_start(loop, &loop->signal_io_watcher, POLLIN);
297 
298   return 0;
299 }
300 
301 
uv__signal_loop_fork(uv_loop_t * loop)302 int uv__signal_loop_fork(uv_loop_t* loop) {
303   struct uv__queue* q;
304 
305   if (loop->signal_pipefd[0] == -1)
306     return 0;
307   uv__io_stop(loop, &loop->signal_io_watcher, POLLIN);
308   uv__close(loop->signal_pipefd[0]);
309   uv__close(loop->signal_pipefd[1]);
310   loop->signal_pipefd[0] = -1;
311   loop->signal_pipefd[1] = -1;
312 
313   uv__queue_foreach(q, &loop->handle_queue) {
314     uv_handle_t* handle = uv__queue_data(q, uv_handle_t, handle_queue);
315     uv_signal_t* sh;
316 
317     if (handle->type != UV_SIGNAL)
318       continue;
319 
320     sh = (uv_signal_t*) handle;
321     sh->caught_signals = 0;
322     sh->dispatched_signals = 0;
323   }
324 
325   return uv__signal_loop_once_init(loop);
326 }
327 
328 
uv__signal_loop_cleanup(uv_loop_t * loop)329 void uv__signal_loop_cleanup(uv_loop_t* loop) {
330   struct uv__queue* q;
331 
332   /* Stop all the signal watchers that are still attached to this loop. This
333    * ensures that the (shared) signal tree doesn't contain any invalid entries
334    * entries, and that signal handlers are removed when appropriate.
335    * It's safe to use uv__queue_foreach here because the handles and the handle
336    * queue are not modified by uv__signal_stop().
337    */
338   uv__queue_foreach(q, &loop->handle_queue) {
339     uv_handle_t* handle = uv__queue_data(q, uv_handle_t, handle_queue);
340 
341     if (handle->type == UV_SIGNAL)
342       uv__signal_stop((uv_signal_t*) handle);
343   }
344 
345   if (loop->signal_pipefd[0] != -1) {
346 #ifdef USE_FFRT
347     if (ffrt_get_cur_task() != NULL) {
348       uv__epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, loop->signal_pipefd[0], NULL);
349     }
350 #endif
351     uv__close(loop->signal_pipefd[0]);
352     loop->signal_pipefd[0] = -1;
353   }
354 
355   if (loop->signal_pipefd[1] != -1) {
356     uv__close(loop->signal_pipefd[1]);
357     loop->signal_pipefd[1] = -1;
358   }
359 }
360 
361 
uv_signal_init(uv_loop_t * loop,uv_signal_t * handle)362 int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
363   int err;
364 
365   err = uv__signal_loop_once_init(loop);
366   if (err)
367     return err;
368 
369   uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
370   handle->signum = 0;
371   handle->caught_signals = 0;
372   handle->dispatched_signals = 0;
373 
374   return 0;
375 }
376 
377 
uv__signal_close(uv_signal_t * handle)378 void uv__signal_close(uv_signal_t* handle) {
379   uv__signal_stop(handle);
380 }
381 
382 
uv_signal_start(uv_signal_t * handle,uv_signal_cb signal_cb,int signum)383 int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
384   return uv__signal_start(handle, signal_cb, signum, 0);
385 }
386 
387 
uv_signal_start_oneshot(uv_signal_t * handle,uv_signal_cb signal_cb,int signum)388 int uv_signal_start_oneshot(uv_signal_t* handle,
389                             uv_signal_cb signal_cb,
390                             int signum) {
391   return uv__signal_start(handle, signal_cb, signum, 1);
392 }
393 
394 
uv__signal_start(uv_signal_t * handle,uv_signal_cb signal_cb,int signum,int oneshot)395 static int uv__signal_start(uv_signal_t* handle,
396                             uv_signal_cb signal_cb,
397                             int signum,
398                             int oneshot) {
399   sigset_t saved_sigmask;
400   int err;
401   uv_signal_t* first_handle;
402 
403   assert(!uv__is_closing(handle));
404 
405   /* If the user supplies signum == 0, then return an error already. If the
406    * signum is otherwise invalid then uv__signal_register will find out
407    * eventually.
408    */
409   if (signum == 0)
410     return UV_EINVAL;
411 
412   /* Short circuit: if the signal watcher is already watching {signum} don't
413    * go through the process of deregistering and registering the handler.
414    * Additionally, this avoids pending signals getting lost in the small
415    * time frame that handle->signum == 0.
416    */
417   if (signum == handle->signum) {
418     handle->signal_cb = signal_cb;
419     return 0;
420   }
421 
422   /* If the signal handler was already active, stop it first. */
423   if (handle->signum != 0) {
424     uv__signal_stop(handle);
425   }
426 
427   uv__signal_block_and_lock(&saved_sigmask);
428 
429   /* If at this point there are no active signal watchers for this signum (in
430    * any of the loops), it's time to try and register a handler for it here.
431    * Also in case there's only one-shot handlers and a regular handler comes in.
432    */
433   first_handle = uv__signal_first_handle(signum);
434   if (first_handle == NULL ||
435       (!oneshot && (first_handle->flags & UV_SIGNAL_ONE_SHOT))) {
436     err = uv__signal_register_handler(signum, oneshot);
437     if (err) {
438       /* Registering the signal handler failed. Must be an invalid signal. */
439       uv__signal_unlock_and_unblock(&saved_sigmask);
440       return err;
441     }
442   }
443 
444   handle->signum = signum;
445   if (oneshot)
446     handle->flags |= UV_SIGNAL_ONE_SHOT;
447 
448   RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
449 
450   uv__signal_unlock_and_unblock(&saved_sigmask);
451 
452   handle->signal_cb = signal_cb;
453   uv__handle_start(handle);
454 
455   return 0;
456 }
457 
458 
uv__signal_event(uv_loop_t * loop,uv__io_t * w,unsigned int events)459 static void uv__signal_event(uv_loop_t* loop,
460                              uv__io_t* w,
461                              unsigned int events) {
462   uv__signal_msg_t* msg;
463   uv_signal_t* handle;
464   char buf[sizeof(uv__signal_msg_t) * 32];
465   size_t bytes, end, i;
466   int r;
467 
468   bytes = 0;
469   end = 0;
470 
471   do {
472     r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
473 
474     if (r == -1 && errno == EINTR)
475       continue;
476 
477     if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
478       /* If there are bytes in the buffer already (which really is extremely
479        * unlikely if possible at all) we can't exit the function here. We'll
480        * spin until more bytes are read instead.
481        */
482       if (bytes > 0)
483         continue;
484 
485       /* Otherwise, there was nothing there. */
486       return;
487     }
488 
489     /* Other errors really should never happen. */
490     if (r == -1) {
491 #ifdef USE_OHOS_DFX
492       UV_LOGF("errno:%{public}d, sig_pfd[0]:%{public}d", errno, loop->signal_pipefd[0]);
493       return;
494 #else
495       abort();
496 #endif
497     }
498 
499     bytes += r;
500 
501     /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */
502     end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
503 
504     for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) {
505       msg = (uv__signal_msg_t*) (buf + i);
506       handle = msg->handle;
507 
508       if (msg->signum == handle->signum) {
509         assert(!(handle->flags & UV_HANDLE_CLOSING));
510         handle->signal_cb(handle, handle->signum);
511       }
512 
513       handle->dispatched_signals++;
514 
515       if (handle->flags & UV_SIGNAL_ONE_SHOT)
516         uv__signal_stop(handle);
517     }
518 
519     bytes -= end;
520 
521     /* If there are any "partial" messages left, move them to the start of the
522      * the buffer, and spin. This should not happen.
523      */
524     if (bytes) {
525       memmove(buf, buf + end, bytes);
526       continue;
527     }
528   } while (end == sizeof buf);
529 }
530 
531 
uv__signal_compare(uv_signal_t * w1,uv_signal_t * w2)532 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
533   int f1;
534   int f2;
535   /* Compare signums first so all watchers with the same signnum end up
536    * adjacent.
537    */
538   if (w1->signum < w2->signum) return -1;
539   if (w1->signum > w2->signum) return 1;
540 
541   /* Handlers without UV_SIGNAL_ONE_SHOT set will come first, so if the first
542    * handler returned is a one-shot handler, the rest will be too.
543    */
544   f1 = w1->flags & UV_SIGNAL_ONE_SHOT;
545   f2 = w2->flags & UV_SIGNAL_ONE_SHOT;
546   if (f1 < f2) return -1;
547   if (f1 > f2) return 1;
548 
549   /* Sort by loop pointer, so we can easily look up the first item after
550    * { .signum = x, .loop = NULL }.
551    */
552   if (w1->loop < w2->loop) return -1;
553   if (w1->loop > w2->loop) return 1;
554 
555   if (w1 < w2) return -1;
556   if (w1 > w2) return 1;
557 
558   return 0;
559 }
560 
561 
uv_signal_stop(uv_signal_t * handle)562 int uv_signal_stop(uv_signal_t* handle) {
563   assert(!uv__is_closing(handle));
564   uv__signal_stop(handle);
565   return 0;
566 }
567 
568 
uv__signal_stop(uv_signal_t * handle)569 static void uv__signal_stop(uv_signal_t* handle) {
570   uv_signal_t* removed_handle;
571   sigset_t saved_sigmask;
572   uv_signal_t* first_handle;
573   int rem_oneshot;
574   int first_oneshot;
575   int ret;
576 
577   /* If the watcher wasn't started, this is a no-op. */
578   if (handle->signum == 0)
579     return;
580 
581   uv__signal_block_and_lock(&saved_sigmask);
582 
583   removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
584   assert(removed_handle == handle);
585   (void) removed_handle;
586 
587   /* Check if there are other active signal watchers observing this signal. If
588    * not, unregister the signal handler.
589    */
590   first_handle = uv__signal_first_handle(handle->signum);
591   if (first_handle == NULL) {
592     uv__signal_unregister_handler(handle->signum);
593   } else {
594     rem_oneshot = handle->flags & UV_SIGNAL_ONE_SHOT;
595     first_oneshot = first_handle->flags & UV_SIGNAL_ONE_SHOT;
596     if (first_oneshot && !rem_oneshot) {
597       ret = uv__signal_register_handler(handle->signum, 1);
598       assert(ret == 0);
599       (void)ret;
600     }
601   }
602 
603   uv__signal_unlock_and_unblock(&saved_sigmask);
604 
605   handle->signum = 0;
606   uv__handle_stop(handle);
607 }
608