ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.pod
(Generate patch)

Comparing libev/ev.pod (file contents):
Revision 1.44 by root, Sat Nov 24 16:57:30 2007 UTC vs.
Revision 1.45 by root, Mon Nov 26 09:52:09 2007 UTC

1102 1102
1103Prepare and check watchers are usually (but not always) used in tandem: 1103Prepare and check watchers are usually (but not always) used in tandem:
1104prepare watchers get invoked before the process blocks and check watchers 1104prepare watchers get invoked before the process blocks and check watchers
1105afterwards. 1105afterwards.
1106 1106
1107You I<must not> call C<ev_loop> or similar functions that enter
1108the current event loop from either C<ev_prepare> or C<ev_check>
1109watchers. Other loops than the current one are fine, however. The
1110rationale behind this is that you do not need to check for recursion in
1111those watchers, i.e. the sequence will always be C<ev_prepare>, blocking,
1112C<ev_check> so if you have one watcher of each kind they will always be
1113called in pairs bracketing the blocking call.
1114
1107Their main purpose is to integrate other event mechanisms into libev and 1115Their main purpose is to integrate other event mechanisms into libev and
1108their use is somewhat advanced. This could be used, for example, to track 1116their use is somewhat advanced. This could be used, for example, to track
1109variable changes, implement your own watchers, integrate net-snmp or a 1117variable changes, implement your own watchers, integrate net-snmp or a
1110coroutine library and lots more. 1118coroutine library and lots more. They are also occasionally useful if
1119you cache some data and want to flush it before blocking (for example,
1120in X programs you might want to do an C<XFlush ()> in an C<ev_prepare>
1121watcher).
1111 1122
1112This is done by examining in each prepare call which file descriptors need 1123This is done by examining in each prepare call which file descriptors need
1113to be watched by the other library, registering C<ev_io> watchers for 1124to be watched by the other library, registering C<ev_io> watchers for
1114them and starting an C<ev_timer> watcher for any timeouts (many libraries 1125them and starting an C<ev_timer> watcher for any timeouts (many libraries
1115provide just this functionality). Then, in the check watcher you check for 1126provide just this functionality). Then, in the check watcher you check for
1137parameters of any kind. There are C<ev_prepare_set> and C<ev_check_set> 1148parameters of any kind. There are C<ev_prepare_set> and C<ev_check_set>
1138macros, but using them is utterly, utterly and completely pointless. 1149macros, but using them is utterly, utterly and completely pointless.
1139 1150
1140=back 1151=back
1141 1152
1142Example: *TODO*. 1153Example: To include a library such as adns, you would add IO watchers
1154and a timeout watcher in a prepare handler, as required by libadns, and
1155in a check watcher, destroy them and call into libadns. What follows is
1156pseudo-code only of course:
1157
1158 static ev_io iow [nfd];
1159 static ev_timer tw;
1160
1161 static void
1162 io_cb (ev_loop *loop, ev_io *w, int revents)
1163 {
1164 // set the relevant poll flags
1165 struct pollfd *fd = (struct pollfd *)w->data;
1166 if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
1167 if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
1168 }
1169
1170 // create io watchers for each fd and a timer before blocking
1171 static void
1172 adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents)
1173 {
1174 int timeout = 3600000;truct pollfd fds [nfd];
1175 // actual code will need to loop here and realloc etc.
1176 adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ()));
1177
1178 /* the callback is illegal, but won't be called as we stop during check */
1179 ev_timer_init (&tw, 0, timeout * 1e-3);
1180 ev_timer_start (loop, &tw);
1181
1182 // create on ev_io per pollfd
1183 for (int i = 0; i < nfd; ++i)
1184 {
1185 ev_io_init (iow + i, io_cb, fds [i].fd,
1186 ((fds [i].events & POLLIN ? EV_READ : 0)
1187 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
1188
1189 fds [i].revents = 0;
1190 iow [i].data = fds + i;
1191 ev_io_start (loop, iow + i);
1192 }
1193 }
1194
1195 // stop all watchers after blocking
1196 static void
1197 adns_check_cb (ev_loop *loop, ev_check *w, int revents)
1198 {
1199 ev_timer_stop (loop, &tw);
1200
1201 for (int i = 0; i < nfd; ++i)
1202 ev_io_stop (loop, iow + i);
1203
1204 adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
1205 }
1143 1206
1144 1207
1145=head2 C<ev_embed> - when one backend isn't enough... 1208=head2 C<ev_embed> - when one backend isn't enough...
1146 1209
1147This is a rather advanced watcher type that lets you embed one event loop 1210This is a rather advanced watcher type that lets you embed one event loop

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines