Exemple #1
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 #2
0
// Given pipes set up, wait for a byte to arrive on one of them
static int
wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_structs, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down)
{
	int r, idx;
	// Poll until one of this signal_info's pipes is ready to read.
	// Once a second, stop to check if the VM is shutting down.
	do {
		struct timeval tv;
		struct timeval *ptv = NULL;
		if (timeout != -1) {
			tv.tv_sec  = timeout / 1000;
			tv.tv_usec = (timeout % 1000)*1000;
			ptv = &tv;
		}
		r = poll (fd_structs, count, timeout);
	} while (keep_trying (r) && !shutting_down ());

	idx = -1;
	if (r == 0)
		idx = timeout;
	else if (r > 0) { // The pipe[s] are ready to read.
		int i;
		for (i = 0; i < count; ++i) {
			signal_info* h = signals [i];
			if (fd_structs[i].revents & POLLIN) {
				int r;
				char c;
				do {
					r = read (mph_int_get (&h->read_fd), &c, 1);
				} while (keep_trying (r) && !shutting_down ());
				if (idx == -1)
					idx = i;
			}
		}
	}

	return idx;
}
Exemple #3
0
static int
wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_structs, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down)
{
	int r, idx;
	do {
		struct timeval tv;
		struct timeval *ptv = NULL;
		if (timeout != -1) {
			tv.tv_sec  = timeout / 1000;
			tv.tv_usec = (timeout % 1000)*1000;
			ptv = &tv;
		}
		r = poll (fd_structs, count, timeout);
	} while (keep_trying (r) && !shutting_down ());

	idx = -1;
	if (r == 0)
		idx = timeout;
	else if (r > 0) {
		int i;
		for (i = 0; i < count; ++i) {
			signal_info* h = signals [i];
			if (fd_structs[i].revents & POLLIN) {
				int r;
				char c;
				do {
					r = read (h->read_fd, &c, 1);
				} while (keep_trying (r) && !shutting_down ());
				if (idx == -1)
					idx = i;
			}
		}
	}

	return idx;
}
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));
			}
		}
	}
}