Commit | Line | Data |
---|---|---|
3aeed370 MB |
1 | package Thread::Signal; |
2 | use Thread qw(async); | |
3 | ||
4 | =head1 NAME | |
5 | ||
6 | Thread::Signal - Start a thread which runs signal handlers reliably | |
7 | ||
8 | =head1 SYNOPSIS | |
9 | ||
10 | use Thread::Signal; | |
11 | ||
12 | $SIG{HUP} = \&some_handler; | |
13 | ||
14 | =head1 DESCRIPTION | |
15 | ||
16 | The C<Thread::Signal> module starts up a special signal handler thread. | |
17 | All signals to the process are delivered to it and it runs the | |
18 | associated C<$SIG{FOO}> handlers for them. Without this module, | |
19 | signals arriving at inopportune moments (such as when perl's internals | |
20 | are in the middle of updating critical structures) cause the perl | |
21 | code of the handler to be run unsafely which can cause memory corruption | |
22 | or worse. | |
23 | ||
24 | =head1 BUGS | |
25 | ||
26 | This module changes the semantics of signal handling slightly in that | |
27 | the signal handler is run separately from the main thread (and in | |
28 | parallel with it). This means that tricks such as calling C<die> from | |
29 | a signal handler behave differently (and, in particular, can't be | |
30 | used to exit directly from a system call). | |
31 | ||
32 | =cut | |
33 | ||
34 | if (!init_thread_signals()) { | |
35 | require Carp; | |
36 | Carp::croak("init_thread_signals failed: $!"); | |
37 | } | |
38 | ||
39 | async { | |
40 | my $sig; | |
41 | while ($sig = await_signal()) { | |
42 | &$sig(); | |
43 | } | |
44 | }; | |
45 | ||
46 | END { | |
47 | kill_sighandler_thread(); | |
48 | } | |
49 | ||
50 | 1; |