* send_signal_etc() now handles a pid_t of -1 specially, but not yet really correct
(that was part of the problem of bug #702). * Fixed send_signal_etc() when you called it with a pid_t of zero: the signals should go to all teams in the calling team's group, not only to the team (for -1, we do the same for now). * Made team_get_process_group_locked() public, and rewrote send_signal_etc() to use it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18684 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
567f38888f
commit
be0e738496
@ -20,6 +20,7 @@ team_id team_create_team(const char *path, const char *name, char **args, int ar
|
||||
status_t wait_for_team(team_id id, status_t *returnCode);
|
||||
void team_remove_team(struct team *team, struct process_group **_freeGroup);
|
||||
void team_delete_team(struct team *team);
|
||||
struct process_group *team_get_process_group_locked(struct team *team, pid_t id);
|
||||
void team_delete_process_group(struct process_group *group);
|
||||
struct team *team_get_kernel_team(void);
|
||||
team_id team_get_kernel_team_id(void);
|
||||
|
@ -290,11 +290,6 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
|
||||
if (signal < 0 || signal > MAX_SIGNO)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (id == 0) {
|
||||
// send a signal to the current team
|
||||
id = thread_get_current_thread()->team->main_thread->id;
|
||||
}
|
||||
|
||||
state = disable_interrupts();
|
||||
|
||||
if (id > 0) {
|
||||
@ -309,23 +304,25 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
|
||||
// send a signal to the specified process group
|
||||
// (the absolute value of the id)
|
||||
|
||||
GRAB_THREAD_LOCK();
|
||||
struct team *team = thread_get_current_thread()->team;
|
||||
struct process_group *group;
|
||||
|
||||
thread = thread_get_thread_struct_locked(-id);
|
||||
if (thread != NULL) {
|
||||
struct process_group *group;
|
||||
// TODO: handle -1 correctly
|
||||
if (id == 0 || id == -1) {
|
||||
// send a signal to the current team
|
||||
id = thread_get_current_thread()->team->main_thread->id;
|
||||
} else
|
||||
id = -id;
|
||||
|
||||
GRAB_TEAM_LOCK();
|
||||
|
||||
group = team_get_process_group_locked(team, id);
|
||||
if (group != NULL) {
|
||||
struct team *team, *next;
|
||||
|
||||
// we need a safe way to get from the thread to the process group
|
||||
id = thread->team->id;
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
GRAB_TEAM_LOCK();
|
||||
|
||||
// get a pointer to the process group
|
||||
team = team_get_team_struct_locked(id);
|
||||
group = team->group;
|
||||
|
||||
for (team = group->teams; team != NULL; team = next) {
|
||||
next = team->group_next;
|
||||
id = team->main_thread->id;
|
||||
@ -342,9 +339,9 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
|
||||
RELEASE_THREAD_LOCK();
|
||||
}
|
||||
|
||||
RELEASE_TEAM_LOCK();
|
||||
GRAB_THREAD_LOCK();
|
||||
}
|
||||
RELEASE_TEAM_LOCK();
|
||||
GRAB_THREAD_LOCK();
|
||||
}
|
||||
|
||||
// ToDo: maybe the scheduler should only be invoked if there is reason to do it?
|
||||
|
@ -1213,25 +1213,6 @@ err1:
|
||||
}
|
||||
|
||||
|
||||
/** This searches the session of the team for the specified group ID.
|
||||
* You must hold the team lock when you call this function.
|
||||
*/
|
||||
|
||||
static struct process_group *
|
||||
get_process_group_locked(struct team *team, pid_t id)
|
||||
{
|
||||
struct process_group *group;
|
||||
struct team_key key;
|
||||
key.id = id;
|
||||
|
||||
group = (struct process_group *)hash_lookup(sGroupHash, &key);
|
||||
if (group != NULL && team->group->session == group->session)
|
||||
return group;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
update_wait_for_any(struct team *team, thread_id child, int32 change)
|
||||
{
|
||||
@ -1252,7 +1233,7 @@ update_wait_for_any(struct team *team, thread_id child, int32 change)
|
||||
|
||||
if (child < 0) {
|
||||
// we wait for all children of the specified process group
|
||||
group = get_process_group_locked(team, -child);
|
||||
group = team_get_process_group_locked(team, -child);
|
||||
} else {
|
||||
// we wait for any children of the current team's group
|
||||
group = team->group;
|
||||
@ -1337,7 +1318,7 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death,
|
||||
return get_team_death_entry(team, child, death, _freeDeath);
|
||||
} else if (child < 0) {
|
||||
// we wait for all children of the specified process group
|
||||
group = get_process_group_locked(team, -child);
|
||||
group = team_get_process_group_locked(team, -child);
|
||||
if (group == NULL)
|
||||
return B_BAD_THREAD_ID;
|
||||
} else {
|
||||
@ -1570,6 +1551,25 @@ team_get_team_struct_locked(team_id id)
|
||||
}
|
||||
|
||||
|
||||
/** This searches the session of the team for the specified group ID.
|
||||
* You must hold the team lock when you call this function.
|
||||
*/
|
||||
|
||||
struct process_group *
|
||||
team_get_process_group_locked(struct team *team, pid_t id)
|
||||
{
|
||||
struct process_group *group;
|
||||
struct team_key key;
|
||||
key.id = id;
|
||||
|
||||
group = (struct process_group *)hash_lookup(sGroupHash, &key);
|
||||
if (group != NULL && team->group->session == group->session)
|
||||
return group;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
team_delete_process_group(struct process_group *group)
|
||||
{
|
||||
@ -2358,7 +2358,7 @@ _user_setpgid(pid_t processID, pid_t groupID)
|
||||
// check if this team can have the group ID; there must be one matching
|
||||
// process ID in the team's session
|
||||
|
||||
struct process_group *group = get_process_group_locked(team, groupID);
|
||||
struct process_group *group = team_get_process_group_locked(team, groupID);
|
||||
if (group) {
|
||||
// we got a group, let's move the team there
|
||||
remove_team_from_group(team, &freeGroup);
|
||||
|
Loading…
Reference in New Issue
Block a user