ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.147
Committed: Mon Mar 16 11:12:53 2020 UTC (4 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-6_57, HEAD
Changes since 1.146: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro::Event - do events the coro-way, with Event
4
5 =head1 SYNOPSIS
6
7 use Coro;
8 use Coro::Event;
9
10 sub keyboard : Coro {
11 my $w = Coro::Event->io(fd => \*STDIN, poll => 'r');
12 while() {
13 print "cmd> ";
14 my $ev = $w->next; my $cmd = <STDIN>;
15 unloop unless $cmd ne "";
16 print "data> ";
17 my $ev = $w->next; my $data = <STDIN>;
18 }
19 }
20
21 loop;
22
23 # wait for input on stdin for one second
24 Coro::Event::do_io (fd => \*STDIN, timeout => 1) & Event::Watcher::R
25 or die "no input received";
26
27 # use a separate thread for event processing, if impossible in main:
28 Coro::async { Event::loop };
29
30 =head1 DESCRIPTION
31
32 This module enables you to create programs using the powerful Event model
33 (and module), while retaining the linear style known from simple or
34 threaded programs.
35
36 This module provides a method and a function for every watcher type
37 (I<flavour>) (see L<Event>). The only difference between these and the
38 watcher constructors from Event is that you do not specify a callback
39 function - it will be managed by this module.
40
41 Your application should just create all necessary threads and then call
42 C<Event::loop>.
43
44 Please note that even programs or modules (such as L<Coro::Handle>) that
45 use "traditional" event-based/continuation style will run more efficient
46 with this module then when using only Event.
47
48 =head1 WARNING
49
50 Please note that Event does not support multithreading. That means that
51 you B<MUST NOT> block in an event callback. Again: In Event callbacks,
52 you I<must never ever> call a Coro function that blocks the current
53 thread.
54
55 While this seems to work superficially, it will eventually cause memory
56 corruption and often results in deadlocks.
57
58 Best practise is to always use B<Coro::unblock_sub> for your callbacks.
59
60 =head1 SEMANTICS
61
62 Whenever Event blocks (e.g. in a call to C<one_event>, C<loop> etc.),
63 this module cede's to all other threads with the same or higher
64 priority. When any threads of lower priority are ready, it will not
65 block but run one of them and then check for events.
66
67 The effect is that coroutines with the same or higher priority than
68 the blocking coroutine will keep Event from checking for events, while
69 coroutines with lower priority are being run, but Event checks for new
70 events after every cede. Note that for this to work you actually need to
71 run the event loop in some thread.
72
73 =head1 FUNCTIONS
74
75 =over 4
76
77 =cut
78
79 package Coro::Event;
80
81 use common::sense;
82
83 use Carp;
84
85 use Coro;
86 use Event qw(loop unloop); # we are re-exporting this for historical reasons
87
88 use XSLoader;
89
90 use base Exporter::;
91
92 our @EXPORT = qw(loop unloop sweep);
93
94 BEGIN {
95 our $VERSION = 6.57;
96
97 local $^W = 0; # avoid redefine warning for Coro::ready;
98 XSLoader::load __PACKAGE__, $VERSION;
99 }
100
101 =item $w = Coro::Event->flavour (args...)
102
103 Create and return a watcher of the given type.
104
105 Examples:
106
107 my $reader = Coro::Event->io (fd => $filehandle, poll => 'r');
108 $reader->next;
109
110 =cut
111
112 =item $w->next
113
114 Wait for and return the next event of the event queue of the watcher. The
115 returned event objects support two methods only: C<hits> and C<got>, both
116 of which return integers: the number this watcher was hit for this event,
117 and the mask of poll events received.
118
119 =cut
120
121 =item do_flavour args...
122
123 Create a watcher of the given type and immediately call its next method,
124 returning the event.
125
126 This is less efficient then calling the constructor once and the next
127 method often, but it does save typing sometimes.
128
129 =cut
130
131 for my $flavour (qw(idle var timer io signal)) {
132 push @EXPORT, "do_$flavour";
133 my $new = \&{"Event::$flavour"};
134 my $class = "Coro::Event::$flavour";
135 my $type = $flavour eq "io" ? 1 : 0;
136 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
137 my $coronew = sub {
138 # how does one do method-call-by-name?
139 # my $w = $class->SUPER::$flavour(@_);
140
141 shift eq Coro::Event::
142 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
143
144 my $w = $new->($class,
145 desc => $flavour,
146 @_,
147 parked => 1,
148 );
149
150 _install_std_cb $w, $type;
151
152 # reblessing due to Event being broken
153 bless $w, $class
154 };
155 *{ $flavour } = $coronew;
156 *{"do_$flavour"} = sub {
157 unshift @_, Coro::Event::;
158 @_ = &$coronew;
159 &Coro::schedule while &_next;
160 $_[0]->cancel;
161 &_event
162 };
163 }
164
165 # do schedule in perl to avoid forcing a stack allocation.
166 # this is about 10% slower, though.
167 sub next($) {
168 &Coro::schedule while &_next;
169 &_event
170 }
171
172 sub Coro::Event::Event::hits { $_[0][3] }
173 sub Coro::Event::Event::got { $_[0][4] }
174
175 =item sweep
176
177 Similar to Event::one_event and Event::sweep: The idle task is called once
178 (this has the effect of jumping back into the Event loop once to serve new
179 events).
180
181 The reason this function exists is that you sometimes want to serve events
182 while doing other work. Calling C<Coro::cede> does not work because
183 C<cede> implies that the current coroutine is runnable and does not call
184 into the Event dispatcher.
185
186 =cut
187
188 sub sweep {
189 Event::one_event 0; # for now
190 }
191
192 # very inefficient
193 our $IDLE = new Coro sub {
194 while () {
195 Event::one_event;
196 Coro::schedule if Coro::nready;
197 }
198 };
199 $IDLE->{desc} = "[Event idle thread]";
200
201 $Coro::idle = $IDLE;
202
203 1;
204
205 =back
206
207 =head1 AUTHOR/SUPPORT/CONTACT
208
209 Marc A. Lehmann <schmorp@schmorp.de>
210 http://software.schmorp.de/pkg/Coro.html
211
212 =cut
213