#include <catta/malloc.h>
#include <catta/timeval.h>
#include <catta/simple-watch.h>
+#include <catta/log.h>
#include "fdutil.h" // catta_set_nonblock
#include "internal.h" // closesocket
char c = 'W';
assert(s);
- write(s->wakeup_pipe[1], &c, sizeof(c));
+ (void)writepipe(s->wakeup_pipe[1], &c, sizeof(c));
s->wakeup_issued = 1;
}
s->wakeup_issued = 0;
- for(;;)
- if (read(s->wakeup_pipe[0], &c, sizeof(c)) != sizeof(c))
+ printf("(clear wake-up"); fflush(stdout); // XXX
+ for(;;) {
+ int n;
+ ioctl(s->wakeup_pipe[0], FIONREAD, &n);
+ printf(" %d", n); fflush(stdout); // XXX
+ if (readpipe(s->wakeup_pipe[0], c, sizeof(c)) != sizeof(c))
break;
+ }
+ printf(")\n"); // XXX
}
static CattaWatch* watch_new(const CattaPoll *api, int fd, CattaWatchEvent event, CattaWatchCallback callback, void *userdata) {
if (!(s = catta_new(CattaSimplePoll, 1)))
return NULL;
+ winsock_init(); // on Windows, pipe uses sockets; no-op on other platforms
if (pipe(s->wakeup_pipe) < 0) {
- catta_free(s);
- return NULL;
+ catta_log_error(__FILE__": pipe() failed: %s", errnostrsocket());
+ goto fail;
}
- catta_set_nonblock(s->wakeup_pipe[0]);
- catta_set_nonblock(s->wakeup_pipe[1]);
+ if (catta_set_nonblock(s->wakeup_pipe[0]) < 0 ||
+ catta_set_nonblock(s->wakeup_pipe[1]) < 0)
+ {
+ catta_log_error(__FILE__": O_NONBLOCK failed: %s", errnostrsocket());
+ goto fail;
+ }
s->api.userdata = s;
CATTA_LLIST_HEAD_INIT(CattaTimeout, s->timeouts);
return s;
+
+fail:
+ catta_free(s);
+ winsock_exit();
+ return NULL;
}
void catta_simple_poll_free(CattaSimplePoll *s) {
catta_free(s->pollfds);
if (s->wakeup_pipe[0] >= 0)
- closesocket(s->wakeup_pipe[0]);
+ closepipe(s->wakeup_pipe[0]);
if (s->wakeup_pipe[1] >= 0)
- closesocket(s->wakeup_pipe[1]);
+ closepipe(s->wakeup_pipe[1]);
catta_free(s);
+ winsock_exit(); // match the winsock_init in catta_simple_poll_new
}
static int rebuild(CattaSimplePoll *s) {
for (;;) {
errno = 0;
+ // XXX debug
+ {
+ printf("(poll %d...", s->n_pollfds);
+ fflush(stdout);
+ }
if (s->poll_func(s->pollfds, s->n_pollfds, s->prepared_timeout, s->poll_func_userdata) < 0) {
- if (errno == EINTR)
+ if (errno == EINTR) {
+ printf(" interrupted)\n"); // XXX
continue;
+ }
s->state = STATE_FAILURE;
+ printf(" FAIL)\n"); // XXX
return -1;
}
assert(s->state == STATE_RAN);
s->state = STATE_DISPATCHING;
- /* We execute only on callback in every iteration */
+ // XXX debug
+ {
+ int i, nready=0, nwatches=0;
+ for(w=s->watches; w; w=w->watches_next)
+ nwatches++;
+ for(i=0; i<s->n_pollfds; i++)
+ if(s->pollfds[i].revents)
+ nready++;
+ if(nready > 0 && s->pollfds[i].revents)
+ printf(" wake-up,");
+ printf(" %d ready, %d watches)\n", nready, nwatches);
+ }
+
+ /* We execute only one callback in every iteration */
/* Check whether the wakeup time has been reached now */
if ((next_timeout = find_next_timeout(s))) {