Author: bonefish Date: 2011-01-13 21:18:18 +0100 (Thu, 13 Jan 2011) New Revision: 40234 Changeset: http://dev.haiku-os.org/changeset/40234 Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h haiku/branches/developer/bonefish/signals/src/system/kernel/port.cpp Log: Team::port_list is now protected by Team::fLock instead of the team spinlock. Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-01-13 20:14:28 UTC (rev 40233) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-01-13 20:18:18 UTC (rev 40234) @@ -268,7 +268,7 @@ struct list image_list; // protected by sImageMutex struct list watcher_list; struct list sem_list; - struct list port_list; + struct list port_list; // protected by fLock struct arch_team arch_info; addr_t user_data; Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/port.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/port.cpp 2011-01-13 20:14:28 UTC (rev 40233) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/port.cpp 2011-01-13 20:18:18 UTC (rev 40234) @@ -599,7 +599,7 @@ struct list queue; { - InterruptsSpinLocker locker(gTeamSpinlock); + TeamLocker teamLocker(team); list_move_to_list(&team->port_list, &queue); } @@ -769,7 +769,7 @@ sPorts[i].select_infos = NULL; { - InterruptsSpinLocker teamLocker(gTeamSpinlock); + TeamLocker teamLocker(team); list_add_item(&team->port_list, &sPorts[i].team_link); } @@ -844,7 +844,13 @@ T(Delete(sPorts[slot])); { - InterruptsSpinLocker teamLocker(gTeamSpinlock); + // get the owning team and remove the port from its ports list + Team* team = Team::Get(sPorts[slot].owner); + if (team == NULL) + return B_BAD_PORT_ID; + BReference<Team> teamReference(team, true); + + TeamLocker teamLocker(team); list_remove_link(&sPorts[slot].team_link); } @@ -1403,20 +1409,36 @@ return B_BAD_PORT_ID; } - InterruptsSpinLocker teamLocker(gTeamSpinlock); - - Team* team = team_get_team_struct_locked(newTeamID); + // get the new team + Team* team = Team::Get(newTeamID); if (team == NULL) { T(OwnerChange(sPorts[slot], newTeamID, B_BAD_TEAM_ID)); return B_BAD_TEAM_ID; } + BReference<Team> teamReference(team, true); + if (team->id == sPorts[slot].owner) + return B_OK; + + // get the old team + Team* oldTeam = Team::Get(sPorts[slot].owner); + if (oldTeam == NULL) { + // old team not available anymore -- the port will be gone soon, too + T(OwnerChange(sPorts[slot], newTeamID, B_BAD_PORT_ID)); + return B_BAD_PORT_ID; + } + BReference<Team> oldTeamReference(oldTeam, true); + + // lock the teams, team with lower ID first + TeamLocker teamLocker1(team->id < oldTeam->id ? team : oldTeam); + TeamLocker teamLocker2(team->id < oldTeam->id ? oldTeam : team); + // transfer ownership to other team list_remove_link(&sPorts[slot].team_link); list_add_item(&team->port_list, &sPorts[slot].team_link); - sPorts[slot].owner = newTeamID; + sPorts[slot].owner = team->id; - T(OwnerChange(sPorts[slot], newTeamID, B_OK)); + T(OwnerChange(sPorts[slot], team->id, B_OK)); return B_OK; }