Changeset 22185

Show
Ignore:
Timestamp:
09/05/07 15:36:38 (15 months ago)
Author:
bonefish
Message:

* Some cleanup in _user_setpgid() (use of autolocking, don't use

shadowing variables).

* Resolved TODO: We wake up the parent if waiting in wait_for_child()

now, if the process group changes.

* Added another TODO: setpgid() is supposed to fail on a child after

it has executed exec*().

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • haiku/trunk/src/system/kernel/team.cpp

    r22161 r22185  
    24122412        struct thread *thread = thread_get_current_thread(); 
    24132413        struct team *currentTeam = thread->team; 
    2414         struct process_group *group = NULL, *freeGroup = NULL; 
    24152414        struct team *team; 
    2416         cpu_status state; 
    24172415        team_id teamID = -1; 
    2418         status_t status = B_OK; 
    2419  
    2420         // TODO: we might want to notify waiting wait_for_child() threads in case 
    2421         //      they wait for children of the former process group ID (see wait_test_4.cpp) 
    24222416 
    24232417        if (groupID < 0) 
     
    24402434                        return B_NOT_ALLOWED; 
    24412435                } 
    2442  
    2443                 status = B_OK; 
    24442436        } else { 
    2445                 state = disable_interrupts(); 
    2446                 GRAB_THREAD_LOCK(); 
     2437                InterruptsSpinLocker _(thread_spinlock); 
    24472438 
    24482439                thread = thread_get_thread_struct_locked(processID); 
     
    24502441                // the thread must be the team's main thread, as that 
    24512442                // determines its process ID 
    2452                 if (thread != NULL && thread == thread->team->main_thread) { 
    2453                         // check if the thread is in a child team of the calling team and 
    2454                         // if it's already a process group leader and in the same session 
    2455                         if (thread->team->parent != currentTeam 
    2456                                 || is_process_group_leader(thread->team) 
    2457                                 || thread->team->session_id != currentTeam->session_id) 
    2458                                 status = B_NOT_ALLOWED; 
    2459                         else 
    2460                                 teamID = thread->team->id; 
    2461                 } else 
    2462                         status = B_BAD_THREAD_ID; 
    2463  
    2464                 RELEASE_THREAD_LOCK(); 
    2465                 restore_interrupts(state); 
    2466         } 
    2467  
    2468         if (status != B_OK) 
    2469                 return status; 
     2443                if (thread == NULL && thread != thread->team->main_thread) 
     2444                        return B_BAD_THREAD_ID; 
     2445 
     2446                // check if the thread is in a child team of the calling team and 
     2447                // if it's already a process group leader and in the same session 
     2448                if (thread->team->parent != currentTeam 
     2449                        || is_process_group_leader(thread->team) 
     2450                        || thread->team->session_id != currentTeam->session_id) { 
     2451                        return B_NOT_ALLOWED; 
     2452                } 
     2453 
     2454                // TODO: According to the standard, the call is also supposed to fail 
     2455                // on a child, when the child already has executed exec*(). 
     2456 
     2457                teamID = thread->team->id; 
     2458        } 
    24702459 
    24712460        // if the group ID is not specified, a new group should be created 
     
    24732462                groupID = processID; 
    24742463 
     2464        struct process_group *group = NULL; 
    24752465        if (groupID == processID) { 
    24762466                // We need to create a new process group for this team 
     
    24802470        } 
    24812471 
    2482         state = disable_interrupts(); 
    2483         GRAB_TEAM_LOCK(); 
     2472        status_t status = B_OK; 
     2473        struct process_group *freeGroup = NULL; 
     2474 
     2475        InterruptsSpinLocker locker(team_spinlock); 
    24842476 
    24852477        team = team_get_team_struct_locked(teamID); 
    24862478        if (team != NULL) { 
    24872479                if (processID == groupID) { 
    2488                         // we created a new process group, let us insert it into the team's session 
     2480                        // we created a new process group, let us insert it into the team's 
     2481                        // session 
    24892482                        insert_group_into_session(team->group->session, group); 
    24902483                        remove_team_from_group(team, &freeGroup); 
    24912484                        insert_team_into_group(group, team); 
    24922485                } else { 
    2493                         // check if this team can have the group ID; there must be one matching 
    2494                         // process ID in the team's session 
    2495  
    2496                         struct process_group *group = 
     2486                        // check if this team can have the group ID; there must be one 
     2487                        // matching process ID in the team's session 
     2488 
     2489                        struct process_group *targetGroup = 
    24972490                                team_get_process_group_locked(team->group->session, groupID); 
    2498                         if (group) { 
     2491                        if (targetGroup != NULL) { 
    24992492                                // we got a group, let's move the team there 
    25002493                                remove_team_from_group(team, &freeGroup); 
    2501                                 insert_team_into_group(group, team); 
     2494                                insert_team_into_group(targetGroup, team); 
    25022495                        } else 
    25032496                                status = B_NOT_ALLOWED; 
     
    25062499                status = B_NOT_ALLOWED; 
    25072500 
    2508         RELEASE_TEAM_LOCK(); 
    2509         restore_interrupts(state); 
     2501        // Changing the process group might have changed the situation for a parent 
     2502        // waiting in wait_for_child(). Hence we notify it. 
     2503        if (status == B_OK) { 
     2504                team->parent->dead_children->condition_variable.NotifyAll(false); 
     2505                team->parent->stopped_children->condition_variable.NotifyAll(false); 
     2506                team->parent->continued_children->condition_variable.NotifyAll(false); 
     2507        } 
     2508 
     2509        locker.Unlock(); 
    25102510 
    25112511        if (status != B_OK && group != NULL) {