Esempio n. 1
0
/**
 * events_network_register(func, cookie, s, op):
 * Register ${func}(${cookie}) to be run when socket ${s} is ready for
 * reading or writing depending on whether ${op} is EVENTS_NETWORK_OP_READ or
 * EVENTS_NETWORK_OP_WRITE.  If there is already an event registration for
 * this ${s}/${op} pair, errno will be set to EEXIST and the function will
 * fail.
 */
int
events_network_register(int (*func)(void *), void * cookie, 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;
	}

	/* Grow the array if necessary. */
	if (((size_t)(s) >= socketlist_getsize(S)) &&
	    (growsocketlist(s + 1) != 0))
		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;

	/* Error out if we already have an event registered. */
	if (*r != NULL) {
		errno = EEXIST;
		goto err0;
	}

	/* Register the new event. */
	if ((*r = events_mkrec(func, cookie)) == NULL)
		goto err0;

	/*
	 * Increment events-registered counter; and if it was zero, start the
	 * inter-select duration clock.
	 */
	if (nev++ == 0)
		events_network_selectstats_startclock();

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Esempio n. 2
0
/**
 * 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);
}