コード例 #1
0
ファイル: signal.c プロジェクト: andyk/load_gen
void
evsig_process(struct event_base *base)
{
	struct evsig_info *sig = &base->sig;
	sig_atomic_t ncalls;
	int i;

	base->sig.evsig_caught = 0;
	for (i = 1; i < NSIG; ++i) {
		ncalls = sig->evsigcaught[i];
		if (ncalls == 0)
			continue;
		sig->evsigcaught[i] -= ncalls;

		evmap_signal_active(base, i, ncalls);
	}
}
コード例 #2
0
ファイル: signal.c プロジェクト: hcqmaker/source-code
/* Callback for when the signal handler write a byte to our signaling socket */
static void
evsig_cb(evutil_socket_t fd, short what, void *arg)
{
	static char signals[1024];
	ev_ssize_t n;
	int i;
	int ncaught[NSIG];
	struct event_base *base;

	base = arg;

	memset(&ncaught, 0, sizeof(ncaught));

	while (1) {
#ifdef _WIN32
		n = recv(fd, signals, sizeof(signals), 0);
#else
		n = read(fd, signals, sizeof(signals));
#endif
		if (n == -1) {
			int err = evutil_socket_geterror(fd);
			if (! EVUTIL_ERR_RW_RETRIABLE(err))
				event_sock_err(1, fd, "%s: recv", __func__);
			break;
		} else if (n == 0) {
			/* XXX warn? */
			break;
		}
		for (i = 0; i < n; ++i) {
			ev_uint8_t sig = signals[i];
			if (sig < NSIG)
				ncaught[sig]++;
		}
	}

	EVBASE_ACQUIRE_LOCK(base, th_base_lock);
	for (i = 0; i < NSIG; ++i) {
		if (ncaught[i])
			evmap_signal_active(base, i, ncaught[i]);
	}
	EVBASE_RELEASE_LOCK(base, th_base_lock);
}
コード例 #3
0
ファイル: signal.c プロジェクト: zyf873753/libevent-for-learn
/* Callback for when the signal handler write a byte to our signaling socket */
static void
evsig_cb(evutil_socket_t fd, short what, void *arg)
{
	static char signals[1024];//用来存放信号处理函数传过来的的信号?
	ev_ssize_t n;
	int i;
	int ncaught[NSIG];//NSIG在哪定义?
	struct event_base *base;

	base = arg;

	memset(&ncaught, 0, sizeof(ncaught));

	while (1) {
		n = recv(fd, signals, sizeof(signals), 0);
		if (n == -1) {
			int err = evutil_socket_geterror(fd);//windows平台这是函数,而linux平台这是宏函数
			if (! EVUTIL_ERR_RW_RETRIABLE(err)) //判断是否可重读写,即检查EINTR和EAGAIN
				event_sock_err(1, fd, "%s: recv", __func__);
			break;
		} else if (n == 0) {
			/* XXX warn? */
			break;
		}
		for (i = 0; i < n; ++i) {
			ev_uint8_t sig = signals[i];
			if (sig < NSIG)
				ncaught[sig]++;//记录传进来的信号
		}
	}

	EVBASE_ACQUIRE_LOCK(base, th_base_lock);//base虽然是在本函数中定义的,貌似在栈上,但是他指向的地址是从外部传过来的,所以需要加锁
	for (i = 0; i < NSIG; ++i) {
		if (ncaught[i])
			evmap_signal_active(base, i, ncaught[i]);//激活base中等待的信号
	}
	EVBASE_RELEASE_LOCK(base, th_base_lock);
}
コード例 #4
0
ファイル: kqueue.c プロジェクト: 00datman/ompi
static int
kq_dispatch(struct event_base *base, struct timeval *tv)
{
	struct kqop *kqop = base->evbase;
	struct kevent *events = kqop->events;
	struct kevent *changes;
	struct timespec ts, *ts_p = NULL;
	int i, n_changes, res;

	if (tv != NULL) {
		TIMEVAL_TO_TIMESPEC(tv, &ts);
		ts_p = &ts;
	}

	/* Build "changes" from "base->changes" */
	EVUTIL_ASSERT(kqop->changes);
	n_changes = kq_build_changes_list(&base->changelist, kqop);
	if (n_changes < 0)
		return -1;

	event_changelist_remove_all(&base->changelist, base);

	/* steal the changes array in case some broken code tries to call
	 * dispatch twice at once. */
	changes = kqop->changes;
	kqop->changes = NULL;

	/* Make sure that 'events' is at least as long as the list of changes:
	 * otherwise errors in the changes can get reported as a -1 return
	 * value from kevent() rather than as EV_ERROR events in the events
	 * array.
	 *
	 * (We could instead handle -1 return values from kevent() by
	 * retrying with a smaller changes array or a larger events array,
	 * but this approach seems less risky for now.)
	 */
	if (kqop->events_size < n_changes) {
		int new_size = kqop->events_size;
		do {
			new_size *= 2;
		} while (new_size < n_changes);

		kq_grow_events(kqop, new_size);
		events = kqop->events;
	}

	EVBASE_RELEASE_LOCK(base, th_base_lock);

	res = kevent(kqop->kq, changes, n_changes,
	    events, kqop->events_size, ts_p);

	EVBASE_ACQUIRE_LOCK(base, th_base_lock);

	EVUTIL_ASSERT(kqop->changes == NULL);
	kqop->changes = changes;

	if (res == -1) {
		if (errno != EINTR) {
			event_warn("kevent");
			return (-1);
		}

		return (0);
	}

	event_debug(("%s: kevent reports %d", __func__, res));

	for (i = 0; i < res; i++) {
		int which = 0;

		if (events[i].flags & EV_ERROR) {
			switch (events[i].data) {

			/* Can occur on delete if we are not currently
			 * watching any events on this fd.  That can
			 * happen when the fd was closed and another
			 * file was opened with that fd. */
			case ENOENT:
			/* Can occur for reasons not fully understood
			 * on FreeBSD. */
			case EINVAL:
				continue;

			/* Can occur on a delete if the fd is closed. */
			case EBADF:
				/* XXXX On NetBSD, we can also get EBADF if we
				 * try to add the write side of a pipe, but
				 * the read side has already been closed.
				 * Other BSDs call this situation 'EPIPE'. It
				 * would be good if we had a way to report
				 * this situation. */
				continue;
			/* These two can occur on an add if the fd was one side
			 * of a pipe, and the other side was closed. */
			case EPERM:
			case EPIPE:
				/* Report read events, if we're listening for
				 * them, so that the user can learn about any
				 * add errors.  (If the operation was a
				 * delete, then udata should be cleared.) */
				if (events[i].udata) {
					/* The operation was an add:
					 * report the error as a read. */
					which |= EV_READ;
					break;
				} else {
					/* The operation was a del:
					 * report nothing. */
					continue;
				}

			/* Other errors shouldn't occur. */
			default:
				errno = events[i].data;
				return (-1);
			}
		} else if (events[i].filter == EVFILT_READ) {
			which |= EV_READ;
		} else if (events[i].filter == EVFILT_WRITE) {
			which |= EV_WRITE;
		} else if (events[i].filter == EVFILT_SIGNAL) {
			which |= EV_SIGNAL;
		}

		if (!which)
			continue;

		if (events[i].filter == EVFILT_SIGNAL) {
			evmap_signal_active(base, events[i].ident, 1);
		} else {
			evmap_io_active(base, events[i].ident, which | EV_ET);
		}
	}

	if (res == kqop->events_size) {
		/* We used all the events space that we have. Maybe we should
		   make it bigger. */
		kq_grow_events(kqop, kqop->events_size * 2);
	}

	return (0);
}
コード例 #5
0
ファイル: kqueue.c プロジェクト: Cue/Pincaster
static int
kq_dispatch(struct event_base *base, struct timeval *tv)
{
	struct kqop *kqop = base->evbase;
	struct kevent *events = kqop->events;
	struct kevent *changes;
	struct timespec ts, *ts_p = NULL;
	int i, n_changes, res;

	if (tv != NULL) {
		TIMEVAL_TO_TIMESPEC(tv, &ts);
		ts_p = &ts;
	}

	/* Build "changes" from "base->changes" */
	EVUTIL_ASSERT(kqop->changes);
	n_changes = kq_build_changes_list(&base->changelist, kqop);
	if (n_changes < 0)
		return -1;

	event_changelist_remove_all(&base->changelist, base);

	/* steal the changes array in case some broken code tries to call
	 * dispatch twice at once. */
	changes = kqop->changes;
	kqop->changes = NULL;

	EVBASE_RELEASE_LOCK(base, th_base_lock);

	res = kevent(kqop->kq, changes, n_changes,
	    events, kqop->events_size, ts_p);

	EVBASE_ACQUIRE_LOCK(base, th_base_lock);

	EVUTIL_ASSERT(kqop->changes == NULL);
	kqop->changes = changes;

	if (res == -1) {
		if (errno != EINTR) {
			event_warn("kevent");
			return (-1);
		}

		return (0);
	}

	event_debug(("%s: kevent reports %d", __func__, res));

	for (i = 0; i < res; i++) {
		int which = 0;

		if (events[i].flags & EV_ERROR) {
			/*
			 * Error messages that can happen, when a delete fails.
			 *   EBADF happens when the file descriptor has been
			 *   closed,
			 *   ENOENT when the file descriptor was closed and
			 *   then reopened.
			 *   EINVAL for some reasons not understood; EINVAL
			 *   should not be returned ever; but FreeBSD does :-\
			 * An error is also indicated when a callback deletes
			 * an event we are still processing.  In that case
			 * the data field is set to ENOENT.
			 */
			if (events[i].data == EBADF ||
			    events[i].data == EINVAL ||
			    events[i].data == ENOENT)
				continue;
			errno = events[i].data;
			return (-1);
		}

		if (events[i].filter == EVFILT_READ) {
			which |= EV_READ;
		} else if (events[i].filter == EVFILT_WRITE) {
			which |= EV_WRITE;
		} else if (events[i].filter == EVFILT_SIGNAL) {
			which |= EV_SIGNAL;
		}

		if (!which)
			continue;

		if (events[i].filter == EVFILT_SIGNAL) {
			evmap_signal_active(base, events[i].ident, 1);
		} else {
			evmap_io_active(base, events[i].ident, which | EV_ET);
		}
	}

	if (res == kqop->events_size) {
		struct kevent *newresult;
		int size = kqop->events_size;
		/* We used all the events space that we have. Maybe we should
		   make it bigger. */
		size *= 2;
		newresult = mm_realloc(kqop->events,
		    size * sizeof(struct kevent));
		if (newresult) {
			kqop->events = newresult;
			kqop->events_size = size;
		}
	}

	return (0);
}