/** * events_timer_cancel(cookie): * Cancel the timer for which the cookie ${cookie} was returned by * events_timer_register. */ void events_timer_cancel(void * cookie) { struct timerrec * t = cookie; /* Remove from the timer queue. */ timerqueue_delete(Q, t->cookie); /* Free the eventrec and timer records. */ events_freerec(t->r); free(t); }
/** * events_timer_register(func, cookie, timeo): * Register ${func}(${cookie}) to be run ${timeo} in the future. Return a * cookie which can be passed to events_timer_cancel or events_timer_reset. */ void * events_timer_register(int (*func)(void *), void * cookie, const struct timeval * timeo) { struct eventrec * r; struct timerrec * t; struct timeval tv; /* Create the timer queue if it doesn't exist yet. */ if (Q == NULL) { if ((Q = timerqueue_init()) == NULL) goto err0; } /* Bundle into an eventrec record. */ if ((r = events_mkrec(func, cookie)) == NULL) goto err0; /* Create a timer record. */ if ((t = malloc(sizeof(struct timerrec))) == NULL) goto err1; t->r = r; memcpy(&t->tv_orig, timeo, sizeof(struct timeval)); /* Compute the absolute timeout. */ if (monoclock_get(&tv)) goto err2; tv.tv_sec += t->tv_orig.tv_sec; if ((tv.tv_usec += t->tv_orig.tv_usec) >= 1000000) { tv.tv_usec -= 1000000; tv.tv_sec += 1; } /* Add this to the timer queue. */ if ((t->cookie = timerqueue_add(Q, &tv, t)) == NULL) goto err2; /* Success! */ return (t); err2: free(t); err1: events_freerec(r); err0: /* Failure! */ return (NULL); }
/** * events_network_cancel(s, op): * Cancel the event registered for the socket/operation pair ${s}/${op}. If * there is no such registration, errno will be set to ENOENT and the * function will fail. */ int events_network_cancel(int s, int op) { struct eventrec ** r; /* Initialize if necessary. */ if (initsocketlist()) goto err0; /* Sanity-check socket number. */ if ((s < 0) || (s >= (int)FD_SETSIZE)) { warn0("Invalid file descriptor for network event: %d", s); goto err0; } /* Sanity-check operation. */ if ((op != EVENTS_NETWORK_OP_READ) && (op != EVENTS_NETWORK_OP_WRITE)) { warn0("Invalid operation for network event: %d", op); goto err0; } /* We have no events registered beyond the end of the array. */ if ((size_t)(s) >= socketlist_getsize(S)) { errno = ENOENT; goto err0; } /* Look up the relevant event pointer. */ if (op == EVENTS_NETWORK_OP_READ) r = &socketlist_get(S, s)->reader; else r = &socketlist_get(S, s)->writer; /* Check if we have an event. */ if (*r == NULL) { errno = ENOENT; goto err0; } /* Free the event. */ events_freerec(*r); *r = NULL; /* * Since there is no longer an event registered for this socket / * operation pair, it doesn't make any sense for it to be ready. */ if (op == EVENTS_NETWORK_OP_READ) FD_CLR(s, &readfds); else FD_CLR(s, &writefds); /* * Decrement events-registered counter; and if it is becoming zero, * stop the inter-select duration clock. */ if (--nev == 0) events_network_selectstats_stopclock(); /* Success! */ return (0); err0: /* Failure! */ return (-1); }