Exemple #1
0
static int
setup_pipes (signal_info** signals, int count, struct pollfd *fd_structs, int *currfd)
{
	int i;
	int r = 0;
	for (i = 0; i < count; ++i) {
		signal_info* h;
		int filedes[2];

		h = signals [i];

		if (mph_int_get (&h->pipecnt) == 0) {
			if ((r = pipe (filedes)) != 0) {
				break;
			}
			h->read_fd  = filedes [0];
			h->write_fd = filedes [1];
		}
		mph_int_inc (&h->pipecnt);
		fd_structs[*currfd].fd = h->read_fd;
		fd_structs[*currfd].events = POLLIN;
		++(*currfd);
	}
	return r;
}
Exemple #2
0
// This handler is registered once for each UnixSignal object. A pipe is maintained
// for each one; Wait users read at one end of this pipe, and default_handler sends
// a write on the pipe for each signal received while the Wait is ongoing.
//
// Notice a fairly unlikely race condition exists here: Because we synchronize with
// pipe teardown, but not install/uninstall (in other words, we are only trying to
// protect against writing on a closed pipe) it is technically possible a full
// uninstall and then an install could complete after signum is checked but before
// the remaining instructions execute. In this unlikely case count could be
// incremented or a byte written on the wrong signal handler.
static void
default_handler (int signum)
{
	int i;
	for (i = 0; i < NUM_SIGNALS; ++i) {
		int fd;
		signal_info* h = &signals [i];
		if (mph_int_get (&h->signum) != signum)
			continue;

		mph_int_inc (&h->count);

		if (!acquire_pipelock_handler (&h->pipelock))
			continue; // Teardown is occurring on this object, no one to send to.

		fd = mph_int_get (&h->write_fd);
		if (fd > 0) { // If any listener exists to write to
			int j,pipecounter;
			char c = signum; // (Value is meaningless)
			pipecounter = mph_int_get (&h->pipecnt); // Write one byte per pipe listener
			for (j = 0; j < pipecounter; ++j) {
				int r;
				do { r = write (fd, &c, 1); } while (keep_trying (r));
			}
		}
		release_pipelock_handler (&h->pipelock);
	}
}
Exemple #3
0
// Set up a signal_info to begin waiting for signal
static int
setup_pipes (signal_info** signals, int count, struct pollfd *fd_structs, int *currfd)
{
	int i;
	int r = 0;
	for (i = 0; i < count; ++i) {
		signal_info* h;
		int filedes[2];

		h = signals [i];

		if (mph_int_get (&h->pipecnt) == 0) { // First listener for this signal_info
			if ((r = pipe (filedes)) != 0) {
				break;
			}
			mph_int_set (&h->read_fd,  filedes [0]);
			mph_int_set (&h->write_fd, filedes [1]);
		}
		mph_int_inc (&h->pipecnt);
		fd_structs[*currfd].fd = mph_int_get (&h->read_fd);
		fd_structs[*currfd].events = POLLIN;
		++(*currfd); // count is verified less than NUM_SIGNALS by caller
	}
	return r;
}
Exemple #4
0
static void
default_handler (int signum)
{
	int i;
	for (i = 0; i < NUM_SIGNALS; ++i) {
		int fd;
		signal_info* h = &signals [i];
		if (mph_int_get (&h->signum) != signum)
			continue;
		mph_int_inc (&h->count);
		fd = mph_int_get (&h->write_fd);
		if (fd > 0) {
			int j,pipecounter;
			char c = signum;
			pipecounter = mph_int_get (&h->pipecnt);
			for (j = 0; j < pipecounter; ++j) {
				int r;
				do { r = write (fd, &c, 1); } while (keep_trying (r));
			}
		}
	}
}