Lines Matching refs:team

15 #include <team.h>
101 void Notify(uint32 eventCode, Team* team);
198 // get the next team -- if there is one, get reference for it
200 Team* team = sTeamHash.NextElement(&fEntry);
201 if (team != NULL)
202 team->AcquireReference();
204 return team;
225 out.Print("team forked, new thread %" B_PRId32, fForkedThread);
269 out.Print("team exec, \"%p\", args:", fPath);
308 SetJobControlState(team_id team, job_control_state newState, Signal* signal)
310 fTeam(team),
319 out.Print("team set job control state, team %" B_PRId32 ", "
343 out.Print("team wait for child, child: %" B_PRId32 ", "
376 out.Print("team wait for child done, team: %" B_PRId32 ", "
381 out.Print("team wait for child failed, error: "
412 TeamNotificationService::Notify(uint32 eventCode, Team* team)
418 event.AddInt32("team", team->id);
419 event.AddPointer("teamStruct", team);
450 dead_children.condition_variable.Init(&dead_children, "team children");
459 job_control_entry->team = this;
556 // create the team object
557 Team* team = new(std::nothrow) Team(id, kernel);
558 if (team == NULL)
560 ObjectDeleter<Team> teamDeleter(team);
563 team->SetName(name);
566 if (team->job_control_entry == NULL || team->fQueuedSignalsCounter == NULL)
570 if (arch_team_init_team_struct(team, kernel) != B_OK)
574 status_t error = user_timer_create_team_timers(team);
579 team->start_time = system_time();
586 /*! \brief Returns the team with the given ID.
587 Returns a reference to the team.
594 Team* team = thread_get_current_thread()->team;
595 team->AcquireReference();
596 return team;
600 Team* team = sTeamHash.Lookup(id);
601 if (team != NULL)
602 team->AcquireReference();
603 return team;
607 /*! \brief Returns the team with the given ID in a locked state.
608 Returns a reference to the team.
614 // get the team
615 Team* team = Get(id);
616 if (team == NULL)
620 team->Lock();
622 // only return the team, when it isn't already dying
623 if (team->state >= TEAM_STATE_SHUTDOWN) {
624 team->Unlock();
625 team->ReleaseReference();
629 return team;
633 /*! Locks the team and its parent team (if any).
634 The caller must hold a reference to the team or otherwise make sure that
636 If the team doesn't have a parent, only the team itself is locked. If the
637 team's parent is the kernel team and \a dontLockParentIfKernel is \c true,
638 only the team itself is locked.
640 \param dontLockParentIfKernel If \c true, the team's parent team is only
641 locked, if it is not the kernel team.
647 // as we don't lock the team, we need to do a trial and error loop.
651 // If the team doesn't have a parent, we're done. Otherwise try to lock
659 // get a temporary reference to the parent, unlock this team, lock the
660 // parent, and re-lock this team
677 /*! Unlocks the team and its parent team (if any).
689 /*! Locks the team, its parent team (if any), and the team's process group.
690 The caller must hold a reference to the team or otherwise make sure that
692 If the team doesn't have a parent, only the team itself is locked.
699 // We hold the group's and the team's lock, but not the parent team's lock.
704 // No success -- unlock the team and let LockTeamAndParent() do the rest of
711 /*! Unlocks the team, its parent team (if any), and the team's process group.
729 // change as long as we don't lock the team, we need to do a trial and error
743 // get a temporary reference to the group, unlock this team, lock the
744 // group, and re-lock this team
827 /*! Adds the given user timer to the team and, if user-defined, assigns it an
830 The caller must hold the team's lock.
840 // don't allow addition of timers when already shutting the team down
855 /*! Removes the given user timer from the team.
857 The caller must hold the team's lock.
872 /*! Deletes all (or all user-defined) user timers of the team.
874 Timer's belonging to the team's threads are not affected.
875 The caller must hold the team's lock.
888 /*! If not at the limit yet, increments the team's user-defined timer count.
904 /*! Subtracts the given count for the team's user-defined timer count.
925 /*! Returns the team's current total CPU time (kernel + user + offset).
929 \param ignoreCurrentRun If \c true and the current thread is one team's
934 \return The team's current total CPU time.
964 /*! Returns the team's current user CPU time.
968 \return The team's current user CPU time.
1080 Team* team = teams;
1081 while (orphaned && team != NULL) {
1082 team->LockTeamAndParent(false);
1084 Team* parent = team->parent;
1090 team->UnlockTeamAndParent();
1092 team = team->group_next;
1143 _dump_team_info(Team* team)
1145 kprintf("TEAM: %p\n", team);
1146 kprintf("id: %" B_PRId32 " (%#" B_PRIx32 ")\n", team->id,
1147 team->id);
1148 kprintf("serial_number: %" B_PRId64 "\n", team->serial_number);
1149 kprintf("name: '%s'\n", team->Name());
1150 kprintf("args: '%s'\n", team->Args());
1151 kprintf("hash_next: %p\n", team->hash_next);
1152 kprintf("parent: %p", team->parent);
1153 if (team->parent != NULL) {
1154 kprintf(" (id = %" B_PRId32 ")\n", team->parent->id);
1158 kprintf("children: %p\n", team->children);
1159 kprintf("num_threads: %d\n", team->num_threads);
1160 kprintf("state: %d\n", team->state);
1161 kprintf("flags: 0x%" B_PRIx32 "\n", team->flags);
1162 kprintf("io_context: %p\n", team->io_context);
1163 if (team->address_space)
1164 kprintf("address_space: %p\n", team->address_space);
1166 (void*)team->user_data, team->user_data_area);
1167 kprintf("free user thread: %p\n", team->free_user_threads);
1168 kprintf("main_thread: %p\n", team->main_thread);
1169 kprintf("thread_list: %p\n", team->thread_list);
1170 kprintf("group_id: %" B_PRId32 "\n", team->group_id);
1171 kprintf("session_id: %" B_PRId32 "\n", team->session_id);
1183 if (thread != NULL && thread->team != NULL)
1184 _dump_team_info(thread->team);
1186 kprintf("No current team!\n");
1199 Team* team = it.Next();) {
1200 if ((team->Name() && strcmp(argv[1], team->Name()) == 0)
1201 || team->id == (team_id)arg) {
1202 _dump_team_info(team);
1209 kprintf("team \"%s\" (%" B_PRId32 ") doesn't exist!\n", argv[1], (team_id)arg);
1217 kprintf("%-*s id %-*s name\n", B_PRINTF_POINTER_WIDTH, "team",
1221 Team* team = it.Next();) {
1222 kprintf("%p%7" B_PRId32 " %p %s\n", team, team->id, team->parent, team->Name());
1247 Team* team = thread_get_current_thread()->team;
1248 TeamLocker teamLocker(team);
1249 if (team->parent == NULL) {
1253 return team->parent->id;
1256 Team* team = Team::GetAndLock(id);
1257 if (team == NULL) {
1264 if (team->parent == NULL) {
1268 parentID = team->parent->id;
1270 team->UnlockAndReleaseReference();
1276 /*! Inserts team \a team into the child list of team \a parent.
1278 The caller must hold the lock of both \a parent and \a team.
1280 \param parent The parent team.
1281 \param team The team to be inserted into \a parent's child list.
1284 insert_team_into_parent(Team* parent, Team* team)
1288 team->siblings_next = parent->children;
1289 parent->children = team;
1290 team->parent = parent;
1294 /*! Removes team \a team from the child list of team \a parent.
1296 The caller must hold the lock of both \a parent and \a team.
1298 \param parent The parent team.
1299 \param team The team to be removed from \a parent's child list.
1302 remove_team_from_parent(Team* parent, Team* team)
1309 if (child == team) {
1315 team->parent = NULL;
1323 /*! Returns whether the given team is a session leader.
1324 The caller must hold the team's lock or its process group's lock.
1327 is_session_leader(Team* team)
1329 return team->session_id == team->id;
1333 /*! Returns whether the given team is a process group leader.
1334 The caller must hold the team's lock or its process group's lock.
1337 is_process_group_leader(Team* team)
1339 return team->group_id == team->id;
1343 /*! Inserts the given team into the given process group.
1344 The caller must hold the process group's lock, the team's lock, and the
1345 team's parent's lock.
1348 insert_team_into_group(ProcessGroup* group, Team* team)
1350 team->group = group;
1351 team->group_id = group->id;
1352 team->session_id = group->Session()->id;
1354 team->group_next = group->teams;
1355 group->teams = team;
1360 /*! Removes the given team from its process group.
1362 The caller must hold the process group's lock, the team's lock, and the
1363 team's parent's lock. Interrupts must be enabled.
1365 \param team The team that'll be removed from its process group.
1368 remove_team_from_group(Team* team)
1370 ProcessGroup* group = team->group;
1374 // the team must be in a process group to let this function have any effect
1380 if (current == team) {
1391 team->group = NULL;
1392 team->group_next = NULL;
1393 team->group_id = -1;
1400 create_team_user_data(Team* team, void* exactAddress = NULL)
1413 status_t result = vm_reserve_address_range(team->id, &address, addressSpec,
1429 team->user_data_area = create_area_etc(team->id, "user area",
1433 if (team->user_data_area < 0)
1434 return team->user_data_area;
1436 team->user_data = (addr_t)address;
1437 team->used_user_data = 0;
1438 team->user_data_size = kTeamUserDataInitialSize;
1439 team->free_user_threads = NULL;
1446 delete_team_user_data(Team* team)
1448 if (team->user_data_area >= 0) {
1449 vm_delete_area(team->id, team->user_data_area, true);
1450 vm_unreserve_address_range(team->id, (void*)team->user_data,
1453 team->user_data = 0;
1454 team->used_user_data = 0;
1455 team->user_data_size = 0;
1456 team->user_data_area = -1;
1457 while (free_user_thread* entry = team->free_user_threads) {
1458 team->free_user_threads = entry->next;
1579 Team* team;
1589 team = thread->team;
1634 // the team deletion process will clean this mess
1641 // set team args and update state
1642 team->Lock();
1643 team->SetArgs(path, teamArgs->flat_args + 1, argCount - 1);
1644 team->state = TEAM_STATE_NORMAL;
1645 team->Unlock();
1652 area_id commPageArea = clone_commpage_area(team->id,
1653 &team->commpage_address);
1669 imageInfo.basic_info.text = team->commpage_address;
1670 imageInfo.text_delta = (ssize_t)(addr_t)team->commpage_address;
1674 image_id image = register_image(team, &imageInfo, sizeof(imageInfo));
1697 err = elf_load_user_image(runtimeLoaderPath.Path(), team, 0,
1704 // done for us by the normal team deletion process
1714 programArgs, team->commpage_address);
1722 team_init_exit_info_on_error(thread_get_current_thread()->team);
1766 // create team object
1767 Team* team = Team::Create(mainThread->id, path, false);
1768 if (team == NULL)
1770 BReference<Team> teamReference(team, true);
1774 loadingInfo.condition.Init(team, "image load");
1777 team->loading_info = &loadingInfo;
1781 // get the parent team
1788 team->Lock();
1791 inherit_parent_user_and_group(team, parent);
1797 team->Unlock();
1801 update_set_id_user_and_group(team, path);
1811 // create a new io_context for this team
1812 team->io_context = vfs_new_io_context(parentIOContext, true);
1813 if (!team->io_context) {
1823 vfs_exec_io_context(team->io_context);
1825 // create an address space for this team
1826 status = VMAddressSpace::Create(team->id, USER_BASE, USER_SIZE, false,
1827 &team->address_space);
1831 team->address_space->SetRandomizingEnabled(
1835 status = create_team_user_data(team);
1839 // insert the team into its parent and the teams hash
1841 team->Lock();
1846 sTeamHash.Insert(team);
1852 insert_team_into_parent(parent, team);
1853 insert_team_into_group(parent->group, team);
1855 team->Unlock();
1858 // notify team listeners
1859 sNotificationService.Notify(TEAM_ADDED, team);
1866 // In case we start the main thread, we shouldn't access the team object
1867 // afterwards, so cache the team's ID.
1868 teamID = team->id;
1870 // Create a kernel thread, but under the context of the new team
1884 // The team has been created successfully, so we keep the reference. Or
1885 // more precisely: It's owned by the team's main thread, now.
1888 // wait for the loader of the new team to finish its work
1891 // resume the team's main thread
1896 // thread, when it finished or aborted loading, or when the team is
1898 // responsible for unsetting `loading_info` in the team structure.
1903 team->Lock();
1904 if (team->loading_info != NULL)
1905 panic("team loading wait complete, but loading_info != NULL");
1906 team->Unlock();
1919 // Remove the team structure from the process group, the parent team, and
1920 // the team hash table and delete the team structure.
1922 team->Lock();
1924 remove_team_from_group(team);
1925 remove_team_from_parent(team->parent, team);
1927 team->Unlock();
1932 sTeamHash.Remove(team);
1937 sNotificationService.Notify(TEAM_REMOVED, team);
1939 delete_team_user_data(team);
1941 team->address_space->Put();
1952 /*! Almost shuts down the current team and loads a new image into it.
1955 This function may only be called in a userland team (caused by one of the
1965 Team* team = thread_get_current_thread()->team;
1971 B_PRId32 "): team %" B_PRId32 "\n", path, argCount, envCount,
1972 team->id));
1977 if (team == team_get_kernel_team())
1982 // make the current thread the team's main thread?
1984 if (currentThread != team->main_thread)
1990 TeamLocker teamLocker(team);
1991 InterruptsSpinLocker debugInfoLocker(team->debug_info.lock);
1993 if (team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED)
1994 nubThreadID = team->debug_info.nub_thread;
1998 for (Thread* thread = team->thread_list; thread != NULL;
2000 if (thread != team->main_thread && thread->id != nubThreadID)
2004 team->DeleteUserTimers(true);
2005 team->ResetSignalsOnExec();
2017 // TODO: remove team resources if there are any left
2024 delete_team_user_data(team);
2025 vm_delete_areas(team->address_space, false);
2026 xsi_sem_undo(team);
2027 delete_owned_ports(team);
2028 sem_delete_owned_sems(team);
2029 remove_images(team);
2030 vfs_exec_io_context(team->io_context);
2031 delete_user_mutex_context(team->user_mutex_context);
2032 team->user_mutex_context = NULL;
2033 delete_realtime_sem_context(team->realtime_sem_context);
2034 team->realtime_sem_context = NULL;
2037 team->address_space->SetRandomizingEnabled(
2040 status = create_team_user_data(team);
2050 // rename the team
2052 team->Lock();
2053 team->SetName(path);
2054 team->Unlock();
2056 // cut the path from the team name and rename the main thread, too
2064 atomic_or(&team->flags, TEAM_FLAG_EXEC_DONE);
2068 update_set_id_user_and_group(team, path);
2072 // notify team listeners
2073 sNotificationService.Notify(TEAM_EXEC, team);
2076 user_thread* userThread = team_allocate_user_thread(team);
2077 // cannot fail (the allocation for the team would have failed already)
2083 status = thread_create_user_stack(currentThread->team, currentThread, NULL,
2106 Team* parentTeam = parentThread->team;
2107 Team* team;
2115 TRACE(("fork_team(): team %" B_PRId32 "\n", parentTeam->id));
2120 // create a new team
2131 // create the team object
2132 team = Team::Create(thread->id, NULL, false);
2133 if (team == NULL)
2137 team->Lock();
2139 team->SetName(parentTeam->Name());
2140 team->SetArgs(parentTeam->Args());
2142 team->commpage_address = parentTeam->commpage_address;
2145 inherit_parent_user_and_group(team, parentTeam);
2148 team->InheritSignalActions(parentTeam);
2150 team->Unlock();
2153 // inherit some team debug flags
2154 team->debug_info.flags |= atomic_get(&parentTeam->debug_info.flags)
2163 // create a new io_context for this team
2164 team->io_context = vfs_new_io_context(parentTeam->io_context, false);
2165 if (!team->io_context) {
2172 team->realtime_sem_context = clone_realtime_sem_context(
2174 if (team->realtime_sem_context == NULL) {
2180 // create an address space for this team
2181 status = VMAddressSpace::Create(team->id, USER_BASE, USER_SIZE, false,
2182 &team->address_space);
2186 // copy all areas of the team
2194 status = create_team_user_data(team, info.address);
2198 thread->user_thread = team_allocate_user_thread(team);
2201 area_id area = vm_copy_area(team->address_space->ID(), info.name,
2236 if (copy_images(parentTeam->id, team) != B_OK)
2239 // insert the team into its parent and the teams hash
2241 team->Lock();
2246 sTeamHash.Insert(team);
2252 insert_team_into_parent(parentTeam, team);
2253 insert_team_into_group(parentTeam->group, team);
2255 team->Unlock();
2258 // notify team listeners
2259 sNotificationService.Notify(TEAM_ADDED, team);
2269 parentThread->name, parentThread->priority, NULL, team->id, thread);
2280 user_debug_team_created(team->id);
2288 // Remove the team structure from the process group, the parent team, and
2289 // the team hash table and delete the team structure.
2291 team->Lock();
2293 remove_team_from_group(team);
2294 remove_team_from_parent(team->parent, team);
2296 team->Unlock();
2301 sTeamHash.Remove(team);
2306 sNotificationService.Notify(TEAM_REMOVED, team);
2308 remove_images(team);
2310 team->address_space->RemoveAndPut();
2312 delete_realtime_sem_context(team->realtime_sem_context);
2316 team->ReleaseReference();
2322 /*! Returns if the specified team \a parent has any children belonging to the
2342 - \code > 0 \endcode: Matching an entry with that team ID.
2347 The caller must hold the lock of the team that \a children belongs to.
2366 = (entry->team ? entry->team->group_id : entry->group_id);
2376 /*! Returns the first job control entry from one of team's dead, continued, or
2379 - \code > 0 \endcode: Matching an entry with that team ID.
2384 The caller must hold \a team's lock.
2386 \param team The team whose dead, stopped, and continued child lists shall be
2397 get_job_control_entry(Team* team, pid_t id, uint32 flags)
2402 entry = get_job_control_entry(team->dead_children, id);
2405 entry = get_job_control_entry(team->continued_children, id);
2408 entry = get_job_control_entry(team->stopped_children, id);
2440 /*! Invoked when the owning team is dying, initializing the entry according to
2443 The caller must hold the owning team's lock and the scheduler lock.
2448 if (team != NULL) {
2449 ASSERT(team->exit.initialized);
2451 group_id = team->group_id;
2452 team->group->AcquireReference();
2455 thread = team->id;
2456 status = team->exit.status;
2457 reason = team->exit.reason;
2458 signal = team->exit.signal;
2459 signaling_user = team->exit.signaling_user;
2460 user_time = team->dead_threads_user_time
2461 + team->dead_children.user_time;
2462 kernel_time = team->dead_threads_kernel_time
2463 + team->dead_children.kernel_time;
2465 team = NULL;
2478 team = other.team;
2496 Team* team = thread->team;
2517 // lock the team
2518 TeamLocker teamLocker(team);
2521 // group of the calling team.
2522 child = originalChild == 0 ? -team->group_id : originalChild;
2525 job_control_entry* entry = get_job_control_entry(team, child, flags);
2534 childrenExist = team->children != NULL;
2536 childrenExist = has_children_in_group(team, -child);
2537 } else if (child != team->id) {
2541 childrenExist = childTeam->parent == team;
2561 team->dead_children.entries.Remove(entry);
2562 team->dead_children.count--;
2565 team_set_job_control_state(entry->team,
2576 team->dead_children.condition_variable.Add(&deadWaitEntry);
2609 struct sigaction& handler = team->SignalActionFor(SIGCHLD);
2624 // unregistered from the team or group. Fill in the returned info.
2654 TeamLocker teamLocker(team);
2655 InterruptsSpinLocker signalLocker(team->signal_lock);
2658 if (is_team_signal_blocked(team, SIGCHLD)) {
2659 if (get_job_control_entry(team, child, flags) == NULL)
2660 team->RemovePendingSignals(SIGNAL_TO_MASK(SIGCHLD));
2667 // When the team is dead, the main thread continues to live in the kernel
2668 // team for a very short time. To avoid surprises for the caller we rather
2679 /*! Fills the team_info structure with information from the specified team.
2680 Interrupts must be enabled. The team must not be locked.
2683 fill_team_info(Team* team, team_info* info, size_t size)
2691 info->team = team->id;
2693 info->image_count = count_images(team);
2696 TeamLocker teamLocker(team);
2697 InterruptsSpinLocker debugInfoLocker(team->debug_info.lock);
2699 info->thread_count = team->num_threads;
2701 info->debugger_nub_thread = team->debug_info.nub_thread;
2702 info->debugger_nub_port = team->debug_info.nub_port;
2703 info->uid = team->effective_uid;
2704 info->gid = team->effective_gid;
2706 strlcpy(info->args, team->Args(), sizeof(info->args));
2710 info->real_uid = team->real_uid;
2711 info->real_gid = team->real_gid;
2712 info->group_id = team->group_id;
2713 info->session_id = team->session_id;
2715 if (team->parent != NULL)
2716 info->parent = team->parent->id;
2720 strlcpy(info->name, team->Name(), sizeof(info->name));
2721 info->start_time = team->start_time;
2734 Team* team = group->teams;
2735 while (team != NULL) {
2736 // the parent team's lock guards the job control entry -- acquire it
2737 team->LockTeamAndParent(false);
2739 if (team->job_control_entry != NULL
2740 && team->job_control_entry->state == JOB_CONTROL_STATE_STOPPED) {
2741 team->UnlockTeamAndParent();
2745 team->UnlockTeamAndParent();
2747 team = team->group_next;
2756 The caller must not hold any team or process group locks.
2782 Signal signal(SIGHUP, SI_USER, B_OK, currentThread->team->id);
2799 // get the team
2800 Team* team = Team::GetAndLock(id);
2801 if (team == NULL)
2803 BReference<Team> teamReference(team, true);
2804 TeamLocker teamLocker(team, true);
2808 if (uid != 0 && uid != team->effective_uid)
2818 Thread* thread = team->thread_list;
2826 kernelTime += team->dead_threads_kernel_time;
2827 userTime += team->dead_threads_user_time;
2833 Team* child = team->children;
2837 Thread* thread = team->thread_list;
2849 kernelTime += team->dead_children.kernel_time;
2850 userTime += team->dead_children.user_time;
2868 // create the team hash table
2871 panic("Failed to init team hash table!");
2891 // create the kernel team
2894 panic("could not create kernel team!\n");
2912 panic("could not create io_context for kernel team!\n");
2915 dprintf("Failed to resize FD table for kernel team!\n");
2917 // stick it in the team hash
2924 add_debugger_command_etc("team", &dump_team_info,
2925 "Dump info about a particular team",
2927 "Prints information about the specified team. If no argument is given\n"
2928 "the current team is selected.\n"
2929 " <id> - The ID of the team.\n"
2930 " <address> - The address of the team structure.\n"
2931 " <name> - The team's name.\n", 0);
2959 /*! Returns a death entry of a child team specified by ID (if any).
2960 The caller must hold the team's lock.
2962 \param team The team whose dead children list to check.
2966 \return The death entry of the matching team, or \c NULL, if no death entry
2967 for the team was found.
2970 team_get_death_entry(Team* team, thread_id child, bool* _deleteEntry)
2975 job_control_entry* entry = get_job_control_entry(team->dead_children,
2978 // remove the entry only, if the caller is the parent of the found team
2980 team->dead_children.entries.Remove(entry);
2981 team->dead_children.count--;
2992 /*! Quick check to see if we have a valid team ID. */
3014 // lock the team, so its session won't change while we're playing with it
3015 Team* team = thread_get_current_thread()->team;
3016 TeamLocker teamLocker(team);
3019 ProcessSession* session = team->group->Session();
3031 // lock the team, so its session won't change while we're playing with it
3032 Team* team = thread_get_current_thread()->team;
3033 TeamLocker teamLocker(team);
3036 ProcessSession* session = team->group->Session();
3047 // lock the team, so its session won't change while we're playing with it
3049 Team* team = thread->team;
3050 TeamLocker teamLocker(team);
3053 ProcessSession* session = team->group->Session();
3071 && session->foreground_group != team->group_id
3072 && team->SignalActionFor(SIGTTOU).sa_handler != SIG_IGN
3074 InterruptsSpinLocker signalLocker(team->signal_lock);
3076 if (!is_team_signal_blocked(team, SIGTTOU)) {
3077 pid_t groupID = team->group_id;
3083 Signal signal(SIGTTOU, SI_USER, B_OK, team->id);
3099 Team* team = team_get_team_struct_locked(id);
3100 if (team == NULL)
3102 return team->effective_uid;
3106 /*! Removes the specified team from the global team hash, from its process
3108 It also moves all of its children to the kernel team.
3111 - \a team's process group's lock,
3112 - the kernel team's lock,
3113 - \a team's parent team's lock (might be the kernel team), and
3114 - \a team's lock.
3117 team_remove_team(Team* team, pid_t& _signalGroup)
3119 Team* parent = team->parent;
3121 // remember how long this team lasted
3122 parent->dead_children.kernel_time += team->dead_threads_kernel_time
3123 + team->dead_children.kernel_time;
3124 parent->dead_children.user_time += team->dead_threads_user_time
3125 + team->dead_children.user_time;
3127 // remove the team from the hash table
3129 sTeamHash.Remove(team);
3133 // The team can no longer be accessed by ID. Navigation to it is still
3136 team->state = TEAM_STATE_DEATH;
3144 if (team->session_id == team->id
3145 && team->group->Session()->controlling_tty != NULL) {
3148 ProcessSession* session = team->group->Session();
3157 remove_team_from_group(team);
3159 // move the team's children to the kernel team
3160 while (Team* child = team->children) {
3161 // remove the child from the current team and add it to the kernel team
3164 remove_team_from_parent(team, child);
3169 &team->stopped_children.entries);
3171 &team->continued_children.entries);
3173 // If the team was a session leader with controlling terminal,
3181 if (childGroup->Session()->id == team->session_id
3182 && childGroup->id != team->group_id) {
3188 // when the team structure is deleted.
3192 remove_team_from_parent(parent, team);
3196 /*! Kills all threads but the main thread of the team and shuts down user
3198 To be called on exit of the team's main thread. No locks must be held.
3200 \param team The team in question.
3201 \return The port of the debugger for the team, -1 if none. To be passed to
3205 team_shutdown_team(Team* team)
3207 ASSERT(thread_get_current_thread() == team->main_thread);
3209 TeamLocker teamLocker(team);
3214 // If a debugger change is in progress for the team, we'll have to
3219 InterruptsSpinLocker debugInfoLocker(team->debug_info.lock);
3221 if (team->debug_info.debugger_changed_condition != NULL) {
3222 team->debug_info.debugger_changed_condition->Add(
3225 } else if (team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
3226 // The team is being debugged. That will stop with the termination
3227 // of the nub thread. Since we set the team state to death, no one
3230 debuggerPort = team->debug_info.debugger_port;
3246 // Mark the team as shutting down. That will prevent new threads from being
3248 team->state = TEAM_STATE_SHUTDOWN;
3251 team->DeleteUserTimers(false);
3253 // deactivate CPU time user timers for the team
3254 InterruptsSpinLocker timeLocker(team->time_lock);
3256 if (team->HasActiveCPUTimeUserTimers())
3257 team->DeactivateCPUTimeUserTimers();
3263 deathEntry.condition.Init(team, "team death");
3266 team->death_entry = &deathEntry;
3269 Thread* thread = team->thread_list;
3271 if (thread != team->main_thread) {
3272 Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id);
3294 team->death_entry = NULL;
3300 /*! Called on team exit to notify threads waiting on the team and free most
3305 team_delete_team(Team* team, port_id debuggerPort)
3312 team_id teamID = team->id;
3314 ASSERT(team->num_threads == 0);
3316 // If someone is waiting for this team to be loaded, but it dies
3320 TeamLocker teamLocker(team);
3322 if (team->loading_info != NULL) {
3324 team->loading_info->result = B_ERROR;
3327 team->loading_info->condition.NotifyAll();
3328 team->loading_info = NULL;
3331 // notify team watchers
3338 &team->watcher_list)) != NULL) {
3346 sNotificationService.Notify(TEAM_REMOVED, team);
3348 // free team resources
3350 delete_user_mutex_context(team->user_mutex_context);
3351 delete_realtime_sem_context(team->realtime_sem_context);
3352 xsi_sem_undo(team);
3353 remove_images(team);
3354 team->address_space->RemoveAndPut();
3356 team->ReleaseReference();
3358 // notify the debugger, that the team is gone
3383 return thread_get_current_thread()->team->id;
3391 // we're the kernel team, so we don't have to go through all
3399 Team* team = team_get_team_struct_locked(id);
3400 if (team == NULL)
3403 team->address_space->Get();
3404 *_addressSpace = team->address_space;
3409 /*! Sets the team's job control state.
3410 The caller must hold the parent team's lock. Interrupts are allowed to be
3412 \a team The team whose job control state shall be set.
3416 entry before releasing the parent team's lock, unless the new state is
3422 team_set_job_control_state(Team* team, job_control_state newState,
3425 if (team == NULL || team->job_control_entry == NULL)
3428 // don't touch anything, if the state stays the same or the team is already
3430 job_control_entry* entry = team->job_control_entry;
3434 T(SetJobControlState(team->id, newState, signal));
3445 team->parent->stopped_children.entries.Remove(entry);
3448 team->parent->continued_children.entries.Remove(entry);
3466 childList = &team->parent->dead_children;
3467 team->parent->dead_children.count++;
3470 childList = &team->parent->stopped_children;
3473 childList = &team->parent->continued_children;
3479 team->parent->dead_children.condition_variable.NotifyAll();
3484 /*! Inits the given team's exit information, if not yet initialized, to some
3486 The caller must not hold the team's lock. Interrupts must be enabled.
3488 \param team The team whose exit info shall be initialized.
3491 team_init_exit_info_on_error(Team* team)
3493 TeamLocker teamLocker(team);
3495 if (!team->exit.initialized) {
3496 team->exit.reason = CLD_KILLED;
3497 team->exit.signal = SIGKILL;
3498 team->exit.signaling_user = geteuid();
3499 team->exit.status = 0;
3500 team->exit.initialized = true;
3505 /*! Adds a hook to the team that is called as soon as this team goes away.
3522 // add watcher, if the team isn't already dying
3523 // get the team
3524 Team* team = Team::GetAndLock(teamID);
3525 if (team == NULL) {
3530 list_add_item(&team->watcher_list, watcher);
3532 team->UnlockAndReleaseReference();
3544 // get team and remove watcher (if present)
3545 Team* team = Team::GetAndLock(teamID);
3546 if (team == NULL)
3552 &team->watcher_list, watcher)) != NULL) {
3555 list_remove_item(&team->watcher_list, watcher);
3560 team->UnlockAndReleaseReference();
3570 /*! Allocates a user_thread structure from the team.
3571 The team lock must be held, unless the function is called for the team's
3575 team_allocate_user_thread(Team* team)
3577 if (team->user_data == 0)
3581 if (struct free_user_thread* entry = team->free_user_threads) {
3583 team->free_user_threads = entry->next;
3591 if (team->user_data_size - team->used_user_data < needed) {
3593 if (resize_area(team->user_data_area,
3594 team->user_data_size + B_PAGE_SIZE) != B_OK) {
3600 team->user_data_size += B_PAGE_SIZE;
3606 = (user_thread*)(team->user_data + team->used_user_data);
3607 team->used_user_data += needed;
3615 The team's lock must not be held. Interrupts must be enabled.
3616 \param team The team the user thread was allocated from.
3620 team_free_user_thread(Team* team, struct user_thread* userThread)
3634 TeamLocker teamLocker(team);
3637 entry->next = team->free_user_threads;
3638 team->free_user_threads = entry;
3734 /*! Associates data with the current team.
3735 When the team is deleted, the data object is notified.
3736 The team acquires a reference to the object.
3745 return thread_get_current_thread()->team->AddData(data);
3749 /*! Dissociates data from the current team.
3754 object is not associated with the current team.
3759 return thread_get_current_thread()->team->RemoveData(data);
3837 // check whether the team exists
3840 Team* team = team_get_team_struct_locked(id);
3841 if (team == NULL)
3844 id = team->id;
3848 // wait for the main thread (it has the same ID as the team)
3858 Team* team = team_get_team_struct_locked(id);
3859 if (team == NULL)
3862 id = team->id;
3866 if (team == sKernelTeam)
3869 // Just kill the team's main thread (it has same ID as the team). The
3870 // cleanup code there will take care of the team.
3878 // get the team
3879 Team* team = Team::Get(id);
3880 if (team == NULL)
3882 BReference<Team> teamReference(team, true);
3885 return fill_team_info(team, info, size);
3901 // get next valid team
3902 Team* team = NULL;
3903 while (slot < lastTeamID && !(team = team_get_team_struct_locked(slot)))
3906 if (team == NULL)
3909 // get a reference to the team and unlock
3910 BReference<Team> teamReference(team);
3915 return fill_team_info(team, info, size);
3932 return thread_get_current_thread()->team->id;
3953 Team* team = thread_get_current_thread()->team;
3954 TeamLocker teamLocker(team);
3955 return team->group_id;
3958 // get the team
3959 Team* team = Team::GetAndLock(id);
3960 if (team == NULL) {
3965 // get the team's process group ID
3966 pid_t groupID = team->group_id;
3968 team->UnlockAndReleaseReference();
3984 Team* team = thread_get_current_thread()->team;
3985 TeamLocker teamLocker(team);
3986 return team->session_id;
3989 // get the team
3990 Team* team = Team::GetAndLock(id);
3991 if (team == NULL) {
3996 // get the team's session ID
3997 pid_t sessionID = team->session_id;
3999 team->UnlockAndReleaseReference();
4106 Team* currentTeam = thread_get_current_thread()->team;
4136 // get the target team
4137 Team* team = Team::Get(processID);
4138 if (team == NULL)
4140 BReference<Team> teamReference(team, true);
4142 // lock the new process group and the team's current process group
4144 // lock the team's current process group
4145 team->LockProcessGroup();
4147 ProcessGroup* oldGroup = team->group;
4149 // This can only happen if the team is exiting.
4150 ASSERT(team->state >= TEAM_STATE_SHUTDOWN);
4172 // no dice -- unlock the team's current process group and relock in
4180 TeamLocker teamLocker(team);
4181 if (team->group == oldGroup)
4192 BReference<ProcessGroup> oldGroupReference(team->group, true);
4193 AutoLocker<ProcessGroup> oldGroupLocker(team->group, true);
4196 // also lock the target team and its parent
4197 team->LockTeamAndParent(false);
4198 TeamLocker parentLocker(team->parent, true);
4199 TeamLocker teamLocker(team, true);
4202 if (team == currentTeam) {
4209 // Calling team != target team. The target team must be a child of
4210 // the calling team and in the same session. (If that's the case it
4212 if (team->parent != currentTeam
4213 || team->session_id != currentTeam->session_id) {
4219 if ((team->flags & TEAM_FLAG_EXEC_DONE) != 0)
4232 group->PublishLocked(team->group->Session());
4233 } else if (group->Session()->id != team->session_id) {
4240 remove_team_from_group(team);
4241 insert_team_into_group(group, team);
4245 team->parent->dead_children.condition_variable.NotifyAll();
4255 Team* team = thread_get_current_thread()->team;
4258 ProcessGroup* group = new(std::nothrow) ProcessGroup(team->id);
4269 // lock the team's current process group, parent, and the team itself
4270 team->LockTeamParentAndProcessGroup();
4271 BReference<ProcessGroup> oldGroupReference(team->group);
4272 AutoLocker<ProcessGroup> oldGroupLocker(team->group, true);
4273 TeamLocker parentLocker(team->parent, true);
4274 TeamLocker teamLocker(team, true);
4276 // the team must not already be a process group leader
4277 if (is_process_group_leader(team))
4280 // remove the team from the old and add it to the new process group
4281 remove_team_from_group(team);
4283 insert_team_into_group(group, team);
4287 team->parent->dead_children.condition_variable.NotifyAll();
4346 Team* team = thread->team;
4351 // set the team exit status
4352 TeamLocker teamLocker(team);
4354 if (!team->exit.initialized) {
4355 team->exit.reason = CLD_EXITED;
4356 team->exit.signal = 0;
4357 team->exit.signaling_user = 0;
4358 team->exit.status = returnValue;
4359 team->exit.initialized = true;
4364 // Stop the thread, if the team is being debugged and that has been
4366 // Note: GCC 13 marks the following call as potentially overflowing, since it thinks team may
4371 if ((atomic_get(&team->debug_info.flags) & B_TEAM_DEBUG_PREVENT_EXIT) != 0)
4377 // thread (if that's not already this one), which will take the team down.
4378 Signal signal(SIGKILL, SI_USER, B_OK, team->id);
4384 _user_kill_team(team_id team)
4386 return kill_team(team);
4447 _user_get_team_usage_info(team_id team, int32 who, team_usage_info* userInfo,
4454 status_t status = common_get_team_usage_info(team, who, &info,
4480 // allocate memory for a copy of the needed team data
4494 // get the team structure
4495 Team* team = Team::GetAndLock(teamID);
4496 if (team == NULL)
4498 BReference<Team> teamReference(team, true);
4499 TeamLocker teamLocker(team, true);
4502 teamClone.id = team->id;
4503 strlcpy(teamClone.name, team->Name(), sizeof(teamClone.name));
4504 teamClone.group_id = team->group_id;
4505 teamClone.session_id = team->session_id;
4506 teamClone.real_uid = team->real_uid;
4507 teamClone.real_gid = team->real_gid;
4508 teamClone.effective_uid = team->effective_uid;
4509 teamClone.effective_gid = team->effective_gid;
4512 ioContext = team->io_context;