ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
(Generate patch)

Comparing Async-Interrupt/Interrupt.pm (file contents):
Revision 1.1 by root, Thu Jul 2 13:41:44 2009 UTC vs.
Revision 1.2 by root, Thu Jul 2 15:13:03 2009 UTC

21 21
22This module implements asynchronous notifications that enable you to 22This module implements asynchronous notifications that enable you to
23signal running perl code form another thread, asynchronously, without 23signal running perl code form another thread, asynchronously, without
24issuing syscalls. 24issuing syscalls.
25 25
26It works by creating an C<Async::Interrupt> object for each such use. This
27object stores a perl and/or a C-level callback that is invoked when the
28C<Async::Interrupt> object gets signalled. It is executed at the next time
29the perl interpreter is running (i.e. it will interrupt a computation, but
30not an XS function or a syscall).
31
32You can signal the C<Async::Interrupt> object either by calling it's C<<
33->signal >> method, or, more commonly, by calling a C function.
34
35The C<< ->signal_func >> returns the address of the C function that is to
36be called (plus an argument to be used during the call). The signalling
37function also takes an integer argument in the range SIG_ATOMIC_MIN to
38SIG_ATOMIC_MAX (guaranteed to allow at least 0..127).
39
40Since this kind of interruption is fast, but can only interrupt a
41I<running> interpreter, there is optional support for also signalling a
42pipe - that means you can also wait for the pipe to become readable while
43
26=over 4 44=over 4
27 45
28=cut 46=cut
29 47
30package Async::Interrupt; 48package Async::Interrupt;
49
50no warnings;
31 51
32BEGIN { 52BEGIN {
33 $VERSION = '0.02'; 53 $VERSION = '0.02';
34 54
35 require XSLoader; 55 require XSLoader;
36 XSLoader::load Async::Interrupt::, $VERSION; 56 XSLoader::load Async::Interrupt::, $VERSION;
37} 57}
38 58
59our $DIED = sub { warn "$@" };
60
39=item $async = new Async::Interrupt key => value... 61=item $async = new Async::Interrupt key => value...
40 62
41Creates a new Async::Interrupt object. You may only use async 63Creates a new Async::Interrupt object. You may only use async
42notifications on this object while it exists, so you need to keep a 64notifications on this object while it exists, so you need to keep a
43reference to it at all times while it is used. 65reference to it at all times while it is used.
51 73
52Registers a perl callback to be invoked whenever the async interrupt is 74Registers a perl callback to be invoked whenever the async interrupt is
53signalled. 75signalled.
54 76
55Note that, since this callback can be invoked at basically any time, it 77Note that, since this callback can be invoked at basically any time, it
56must not modify any well-known global variables such as C<$/>, C<$@> or 78must not modify any well-known global variables such as C<$/> without
57C<$!>, without restoring them again before returning. 79restoring them again before returning.
58 80
81The exceptions are C<$!> and C<$@>, which are saved and restored by
82Async::Interrupt.
83
84If the callback should throw an exception, then it will be caught,
85and C<$Async::Interrupt::DIED> will be called with C<$@> containing
86the exception. The default will simply C<warn> about the message and
87continue.
88
59=item c_cb => [$c_func, $c_data] 89=item c_cb => [$c_func, $c_arg]
60 90
61Registers a C callback the be invoked whenever the async interrupt is 91Registers a C callback the be invoked whenever the async interrupt is
62signalled. 92signalled.
63 93
64The C callback must have the following prototype: 94The C callback must have the following prototype:
65 95
66 void c_func (pTHX_ void *c_data, int value); 96 void c_func (pTHX_ void *c_arg, int value);
67 97
68Both C<$c_func> and C<$c_data> must be specified as integers/IVs. 98Both C<$c_func> and C<$c_arg> must be specified as integers/IVs, and
99C<$value> is the C<value> passed to some earlier call to either C<$signal>
100or the C<signal_func> function.
69 101
70Note that, because the callback can be invoked at almost any time, you 102Note that, because the callback can be invoked at almost any time, you
71have to be careful at saving and restoring global variables that Perl 103have to be careful at saving and restoring global variables that Perl
72might use, most notably C<errno>. The callback itself runs as part of the 104might use (the excetpion is C<errno>, which is aved and restored by
73perl context, so you can call any perl functions and modify any perl data 105Async::Interrupt). The callback itself runs as part of the perl context,
74structures. 106so you can call any perl functions and modify any perl data structures (in
107which case the requireemnts set out for C<cb> apply as well).
75 108
76=item fh => $fileno_or_fh 109=item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
77 110
78Specifies a file descriptor (or file handle) that should be signalled 111Specifies two file descriptors (or file handles) that should be signalled
79whenever the async interrupt is signalled. This means a single octet will 112whenever the async interrupt is signalled. This means a single octet will
80be written to it, and before the callback is being invoked, it will be 113be written to it, and before the callback is being invoked, it will be
81read again. Due to races, it is unlikely but possible that multiple octets 114read again. Due to races, it is unlikely but possible that multiple octets
82are written, therefore, it is recommended that the file handle is in 115are written. It is required that the file handles are both in nonblocking
83nonblocking mode. 116mode.
84 117
85(You can get a portable pipe and set non-blocking mode portably by using 118(You can get a portable pipe and set non-blocking mode portably by using
86e.g. L<AnyEvent::Util> from the L<AnyEvent> distro). 119e.g. L<AnyEvent::Util> from the L<AnyEvent> distro).
87 120
88The object will keep a reference to the file handle. 121The object will keep a reference to the file handles.
89 122
90This can be used to ensure that async notifications will interrupt event 123This can be used to ensure that async notifications will interrupt event
91frameworks as well. 124frameworks as well.
92 125
93=back 126=back
95=cut 128=cut
96 129
97sub new { 130sub new {
98 my ($class, %arg) = @_; 131 my ($class, %arg) = @_;
99 132
100 my $self = _alloc $arg{cb}, @{$arg{c_cb}}[0,1], $arg{fh}; 133 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class
101 bless \$self, $class
102} 134}
103 135
104=item ($signal_func, $signal_arg) = $async->signal_cb 136=item ($signal_func, $signal_arg) = $async->signal_func
105 137
106Returns the address of a function to call asynchronously. The function has 138Returns the address of a function to call asynchronously. The function has
107the following prototype and needs to be passed the specified C<$c_arg>, 139the following prototype and needs to be passed the specified C<$c_arg>,
108which is a C<void *> cast to C<IV>: 140which is a C<void *> cast to C<IV>:
109 141
111 143
112An example call would look like: 144An example call would look like:
113 145
114 signal_func (signal_arg, 0); 146 signal_func (signal_arg, 0);
115 147
116The function is safe toc all from within signal and thread contexts, at 148The function is safe to call from within signal and thread contexts, at
117any time. The specified C<value> is passed to both C and Perl callback. 149any time. The specified C<value> is passed to both C and Perl callback.
150
151C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
152portable).
118 153
119If the function is called while the Async::Interrupt object is already 154If the function is called while the Async::Interrupt object is already
120signaled but before the callbacks are being executed, then the stored 155signaled but before the callbacks are being executed, then the stored
121C<value> is being overwritten. Due to the asynchronous nature of the code, 156C<value> is either the old or the new one. Due to the asynchronous
122the C<value> can even be passed to two consecutive invocations of the 157nature of the code, the C<value> can even be passed to two consecutive
123callback. 158invocations of the callback.
124 159
125=item $async->signal ($value=0) 160=item $async->signal ($value=0)
126 161
127This signals the given async object from Perl code. Semi-obviously, this 162This signals the given async object from Perl code. Semi-obviously, this
128will instantly trigger the callback invocation. 163will instantly trigger the callback invocation.
129 164
165C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
166portable).
167
168=item $async->block
169
170Sometimes you need a "critical section" of code where
171
172=item $async->unblock
173
130=cut 174=cut
131 175
1321; 1761;
133 177
134=back 178=back
179
180=head1 EXAMPLE
181
182#TODO
183
184=head1 IMPLEMENTATION DETAILS AND LIMITATIONS
185
186This module works by "hijacking" SIGKILL, which is guarenteed to be always
187available in perl, but also cannot be caught, so is always available.
188
189Basically, this module fakes the receive of a SIGKILL signal and
190then catches it. This makes normal signal handling slower (probably
191unmeasurably), but has the advantage of not requiring a special runops nor
192slowing down normal perl execution a bit.
193
194It assumes that C<sig_atomic_t> and C<int> are both exception-safe to
195modify (C<sig_atomic_> is used by this module, and perl itself uses
196C<int>, so we can assume that this is quite portbale, at least w.r.t.
197signals).
135 198
136=head1 AUTHOR 199=head1 AUTHOR
137 200
138 Marc Lehmann <schmorp@schmorp.de> 201 Marc Lehmann <schmorp@schmorp.de>
139 http://home.schmorp.de/ 202 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines