… | |
… | |
124 | =back |
124 | =back |
125 | |
125 | |
126 | For libev, you would typically use an C<ev_async> watcher: the |
126 | For libev, you would typically use an C<ev_async> watcher: the |
127 | C<want_poll> callback would invoke C<ev_async_send> to wake up the event |
127 | C<want_poll> callback would invoke C<ev_async_send> to wake up the event |
128 | loop. Inside the callback set for the watcher, one would call C<eio_poll |
128 | loop. Inside the callback set for the watcher, one would call C<eio_poll |
129 | ()> (followed by C<ev_async_send> again if C<eio_poll> indicates that not |
129 | ()>. |
130 | all requests have been handled yet). The race is taken care of because |
130 | |
131 | libev resets/rearms the async watcher before calling your callback, |
131 | If C<eio_poll ()> is configured to not handle all results in one go |
132 | and therefore, before calling C<eio_poll>. This might result in (some) |
132 | (i.e. it returns C<-1>) then you should start an idle watcher that calls |
133 | spurious wake-ups, but is generally harmless. |
133 | C<eio_poll> until it returns something C<!= -1>. |
|
|
134 | |
|
|
135 | A full-featured conenctor between libeio and libev would look as follows |
|
|
136 | (if C<eio_poll> is handling all requests, it can of course be simplified a |
|
|
137 | lot by removing the idle watcher logic): |
|
|
138 | |
|
|
139 | static struct ev_loop *loop; |
|
|
140 | static ev_idle repeat_watcher; |
|
|
141 | static ev_async ready_watcher; |
|
|
142 | |
|
|
143 | /* idle watcher callback, only used when eio_poll */ |
|
|
144 | /* didn't handle all results in one call */ |
|
|
145 | static void |
|
|
146 | repeat (EV_P_ ev_idle *w, int revents) |
|
|
147 | { |
|
|
148 | if (eio_poll () != -1) |
|
|
149 | ev_idle_stop (EV_A_ w); |
|
|
150 | } |
|
|
151 | |
|
|
152 | /* eio has some results, process them */ |
|
|
153 | static void |
|
|
154 | ready (EV_P_ ev_async *w, int revents) |
|
|
155 | { |
|
|
156 | if (eio_poll () == -1) |
|
|
157 | ev_idle_start (EV_A_ &repeat_watcher); |
|
|
158 | } |
|
|
159 | |
|
|
160 | /* wake up the event loop */ |
|
|
161 | static void |
|
|
162 | want_poll (void) |
|
|
163 | { |
|
|
164 | ev_async_send (loop, &ready_watcher) |
|
|
165 | } |
|
|
166 | |
|
|
167 | void |
|
|
168 | my_init_eio () |
|
|
169 | { |
|
|
170 | loop = EV_DEFAULT; |
|
|
171 | |
|
|
172 | ev_idle_init (&repeat_watcher, repeat); |
|
|
173 | ev_async_init (&ready_watcher, ready); |
|
|
174 | ev_async_start (loop &watcher); |
|
|
175 | |
|
|
176 | eio_init (want_poll, 0); |
|
|
177 | } |
134 | |
178 | |
135 | For most other event loops, you would typically use a pipe - the event |
179 | For most other event loops, you would typically use a pipe - the event |
136 | loop should be told to wait for read readiness on the read end. In |
180 | loop should be told to wait for read readiness on the read end. In |
137 | C<want_poll> you would write a single byte, in C<done_poll> you would try |
181 | C<want_poll> you would write a single byte, in C<done_poll> you would try |
138 | to read that byte, and in the callback for the read end, you would call |
182 | to read that byte, and in the callback for the read end, you would call |
139 | C<eio_poll>. The race is avoided here because the event loop should invoke |
183 | C<eio_poll>. |
140 | your callback again and again until the byte has been read (as the pipe |
184 | |
141 | read callback does not read it, only C<done_poll>). |
185 | You don't have to take special care in the case C<eio_poll> doesn't handle |
|
|
186 | all requests, as the done callback will not be invoked, so the event loop |
|
|
187 | will still signal readyness for the pipe until I<all> results have been |
|
|
188 | processed. |
142 | |
189 | |
143 | |
190 | |
144 | =head1 HIGH LEVEL REQUEST API |
191 | =head1 HIGH LEVEL REQUEST API |
145 | |
192 | |
146 | Libeio has both a high-level API, which consists of calling a request |
193 | Libeio has both a high-level API, which consists of calling a request |
… | |
… | |
323 | } |
370 | } |
324 | |
371 | |
325 | =item eio_realpath (const char *path, int pri, eio_cb cb, void *data) |
372 | =item eio_realpath (const char *path, int pri, eio_cb cb, void *data) |
326 | |
373 | |
327 | Similar to the realpath libc function, but unlike that one, result is |
374 | Similar to the realpath libc function, but unlike that one, result is |
328 | C<0> on failure and the length of the returned path in C<ptr2> - this is |
375 | C<-1> on failure and the length of the returned path in C<ptr2> (which is |
329 | similar to readlink. |
376 | not 0-terminated) - this is similar to readlink. |
330 | |
377 | |
331 | =item eio_stat (const char *path, int pri, eio_cb cb, void *data) |
378 | =item eio_stat (const char *path, int pri, eio_cb cb, void *data) |
332 | |
379 | |
333 | =item eio_lstat (const char *path, int pri, eio_cb cb, void *data) |
380 | =item eio_lstat (const char *path, int pri, eio_cb cb, void *data) |
334 | |
381 | |