void centralized_done_with_process_id(int pid, int in_group) { Child_Status *st; int keep_unused = 1; /* assume that any process can be in a new group */ pthread_mutex_lock(&child_wait_lock); /* protects unused_pid_statuses */ pthread_mutex_lock(&child_status_lock); for (st = child_statuses; st; st = st->next) { if (st->pid == pid) { if (!st->done) { if (keep_unused) { st->next_unused = unused_pid_statuses; unused_pid_statuses = st; if (st->signal_fd) remove_group_signal_fd(st->signal_fd); } else st->unneeded = 1; st->signal_fd = NULL; } break; } } if (st && (keep_unused || st->done)) { /* remove it from normal list: */ raw_get_child_status(pid, NULL, 0, 1, st->done); } pthread_mutex_unlock(&child_status_lock); pthread_mutex_unlock(&child_wait_lock); }
int centralized_get_child_status(int pid, int in_group, int can_check_group, int *status) { int found = 0; /* Check specific pid, in case the child has its own group (either given by Racket or given to itself): */ if (can_check_group) { pid_t pid2; int status; do { pid2 = waitpid((pid_t)pid, &status, WNOHANG); } while ((pid2 == -1) && (errno == EINTR)); if (pid2 > 0) add_child_status(pid, extract_child_status(status)); } pthread_mutex_lock(&child_status_lock); found = raw_get_child_status(pid, status, 1, 1, 1); pthread_mutex_unlock(&child_status_lock); /* printf("centralized_get_child_status found %i pid %i status %i\n", found, pid, *status); */ return found; }
static int centralized_register_child(int pid, int in_group, rktio_signal_handle_t *signal_fd, int *status) { int found = 0; pthread_mutex_lock(&child_status_lock); /* The child may have terminated already: */ found = raw_get_child_status(pid, status, 0, 0, 0); if (!found) { /* Create a record for the child: */ Child_Status *st; st = malloc(sizeof(Child_Status)); st->pid = pid; st->signal_fd = signal_fd; st->status = 0; st->unneeded = 0; st->done = 0; st->in_group = in_group; st->next = child_statuses; child_statuses = st; st->next_unused = NULL; if (in_group) add_group_signal_fd(signal_fd); } pthread_mutex_unlock(&child_status_lock); return found; }
int scheme_places_register_child(int pid, int is_group, void *signal_fd, int *status) { int found = 0; mzrt_mutex_lock(child_status_lock); /* The child may have terminated already: */ found = raw_get_child_status(pid, status, 0, 0, 0); if (!found) { /* Create a record for the child: */ Child_Status *st; st = malloc(sizeof(Child_Status)); st->pid = pid; st->signal_fd = signal_fd; st->status = 0; st->unneeded = 0; st->done = 0; st->is_group = is_group; st->next = child_statuses; child_statuses = st; st->next_unused = NULL; if (is_group) add_group_signal_fd(signal_fd); } mzrt_mutex_unlock(child_status_lock); return found; }
void scheme_done_with_process_id(int pid, int is_group) { Child_Status *st; mzrt_mutex_lock(child_wait_lock); /* protects child_group_statuses */ mzrt_mutex_lock(child_status_lock); for (st = child_statuses; st; st = st->next) { if (st->pid == pid) { if (!st->done) { if (is_group) { st->next_group = child_group_statuses; child_group_statuses = st; if (st->signal_fd) remove_group_signal_fd(st->signal_fd); } else st->unneeded = 1; st->signal_fd = NULL; } break; } } if (st && (is_group || st->done)) { /* remove it from normal list: */ raw_get_child_status(pid, NULL, 0, 1, !st->done); } mzrt_mutex_unlock(child_status_lock); mzrt_mutex_unlock(child_wait_lock); }
static void add_child_status(int pid, int status) { Child_Status *st; /* Search for existing record, which will have a signal_fd: */ pthread_mutex_lock(&child_status_lock); for (st = child_statuses; st; st = st->next) { if (st->pid == pid) break; } if (!st) { /* must have terminated before it was registered (and since we detected it, it must not be in a group) */ st = malloc(sizeof(Child_Status)); st->pid = pid; st->signal_fd = NULL; st->next = child_statuses; child_statuses = st; st->next_unused = NULL; st->unneeded = 0; st->in_group = 0; } st->status = status; st->done = 1; if (st->signal_fd && st->in_group) remove_group_signal_fd(st->signal_fd); if (st->signal_fd) rktio_signal_received_at(st->signal_fd); if (st->unneeded) (void)raw_get_child_status(st->pid, NULL, 1, 1, 1); pthread_mutex_unlock(&child_status_lock); }
int scheme_get_child_status(int pid, int is_group, int *status) { int found = 0; /* Check specific pid, in case the child has its own group (either given by Racket or given to itself): */ { pid_t pid2; int status; do { pid2 = waitpid((pid_t)pid, &status, WNOHANG); } while ((pid2 == -1) && (errno == EINTR)); if (pid2 > 0) add_child_status(pid, status); } mzrt_mutex_lock(child_status_lock); found = raw_get_child_status(pid, status, 1, 1, 1); mzrt_mutex_unlock(child_status_lock); /* printf("scheme_get_child_status found %i pid %i status %i\n", found, pid, *status); */ return found; }
int scheme_get_child_status(int pid, int is_group, int *status) { int found = 0; if (is_group) { /* need to specifically try the pid, since we don't wait on other process groups in the background thread */ pid_t pid2; int status; do { pid2 = waitpid((pid_t)pid, &status, WNOHANG); } while ((pid2 == -1) && (errno == EINTR)); if (pid2 > 0) add_child_status(pid, status); } mzrt_mutex_lock(child_status_lock); found = raw_get_child_status(pid, status, 1, 1, 1); mzrt_mutex_unlock(child_status_lock); /* printf("scheme_get_child_status found %i pid %i status %i\n", found, pid, *status); */ return found; }