/** * events_timer_register_double(func, cookie, timeo): * As events_timer_register, but ${timeo} is a double-precision floating point * value specifying a number of seconds. */ void * events_timer_register_double(int (*func)(void *), void * cookie, double timeo) { struct timeval tv; /* Convert timeo to a struct timeval. */ tv.tv_sec = timeo; tv.tv_usec = (timeo - tv.tv_sec) * 1000000.0; /* Schedule the timeout. */ return (events_timer_register(func, cookie, &tv)); }
/** * network_sleep(timeo, callback, cookie): * Register a callback to be performed by network_select once the specified * timeout has expired. Return a handle which can be passed to * network_desleep(). */ int network_sleep(struct timeval * timeo, network_callback * callback, void * cookie) { struct sleeper s; struct sleeper * sp = NULL; /* Silence bogus gcc warning. */ size_t h; /* Initialize array if required. */ if (sleepers == NULL) { if ((sleepers = sleepers_init(0)) == NULL) goto err0; } /* Construct sleeper record. */ s.callback = callback; s.cookie = cookie; s.event_cookie = NULL; /* Search for empty space. */ for (h = 0; h < sleepers_getsize(sleepers); h++) { sp = *sleepers_get(sleepers, h); if (sp->event_cookie == NULL) { /* Use this one. */ memcpy(sp, &s, sizeof(struct sleeper)); break; } } /* If we didn't find an empty space, add a new sleeper. */ if (h == sleepers_getsize(sleepers)) { /* Don't have too many sleepers... */ if (h == 1024) { warn0("Too many sleepers"); goto err0; } /* Allocate a record. */ if ((sp = malloc(sizeof(struct sleeper))) == NULL) goto err0; /* Copy data in. */ memcpy(sp, &s, sizeof(struct sleeper)); /* Append the record. */ if (sleepers_append(sleepers, &sp, 1)) goto err1; } /* Register the timer event. */ if ((sp->event_cookie = events_timer_register(callback_timer, sp, timeo)) == NULL) goto err0; /* Success! */ return ((int)h); err1: free(sp); err0: /* Failure! */ return (-1); }