Merged signals-merge branch into trunk with the following changes:

* Reorganized the kernel locking related to threads and teams.
* We now discriminate correctly between process and thread signals. Signal
  handlers have been moved to teams. Fixes #5679.
* Implemented real-time signal support, including signal queuing, SA_SIGINFO
  support, sigqueue(), sigwaitinfo(), sigtimedwait(), waitid(), and the addition
  of the real-time signal range. Closes #1935 and #2695.
* Gave SIGBUS a separate signal number. Fixes #6704.
* Implemented <time.h> clock and timer support, and fixed/completed alarm() and
  [set]itimer(). Closes #5682.
* Implemented support for thread cancellation. Closes #5686.
* Moved send_signal() from <signal.h> to <OS.h>. Fixes #7554.
* Lots over smaller more or less related changes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42116 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2011-06-12 00:00:23 +00:00
parent ccd31b93f1
commit 24df65921b
235 changed files with 14975 additions and 6594 deletions
+15 -88
View File
@@ -1764,62 +1764,18 @@ replace_vnode_if_disconnected(struct fs_mount* mount,
This is not a cheap function and should be used with care and rarely.
TODO: there is currently no means to stop a blocking read/write!
*/
void
static void
disconnect_mount_or_vnode_fds(struct fs_mount* mount,
struct vnode* vnodeToDisconnect)
{
// iterate over all teams and peek into their file descriptors
int32 nextTeamID = 0;
TeamListIterator teamIterator;
while (Team* team = teamIterator.Next()) {
BReference<Team> teamReference(team, true);
while (true) {
struct io_context* context = NULL;
bool contextLocked = false;
Team* team = NULL;
team_id lastTeamID;
cpu_status state = disable_interrupts();
SpinLocker teamsLock(gTeamSpinlock);
lastTeamID = peek_next_thread_id();
if (nextTeamID < lastTeamID) {
// get next valid team
while (nextTeamID < lastTeamID
&& !(team = team_get_team_struct_locked(nextTeamID))) {
nextTeamID++;
}
if (team) {
context = (io_context*)team->io_context;
// Some acrobatics to lock the context in a safe way
// (cf. _kern_get_next_fd_info() for details).
GRAB_THREAD_LOCK();
teamsLock.Unlock();
contextLocked = mutex_lock_threads_locked(&context->io_mutex)
== B_OK;
RELEASE_THREAD_LOCK();
nextTeamID++;
}
}
teamsLock.Unlock();
restore_interrupts(state);
if (context == NULL)
break;
// we now have a context - since we couldn't lock it while having
// safe access to the team structure, we now need to lock the mutex
// manually
if (!contextLocked) {
// team seems to be gone, go over to the next team
continue;
}
// the team cannot be deleted completely while we're owning its
// io_context mutex, so we can safely play with it now
// lock the I/O context
io_context* context = team->io_context;
MutexLocker contextLocker(context->io_mutex);
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->root,
sRoot, true);
@@ -1843,8 +1799,6 @@ disconnect_mount_or_vnode_fds(struct fs_mount* mount,
put_fd(descriptor);
}
}
mutex_unlock(&context->io_mutex);
}
}
@@ -7828,38 +7782,15 @@ _kern_get_next_fd_info(team_id teamID, uint32* _cookie, fd_info* info,
if (infoSize != sizeof(fd_info))
return B_BAD_VALUE;
struct io_context* context = NULL;
Team* team = NULL;
cpu_status state = disable_interrupts();
GRAB_TEAM_LOCK();
bool contextLocked = false;
team = team_get_team_struct_locked(teamID);
if (team) {
// We cannot lock the IO context while holding the team lock, nor can
// we just drop the team lock, since it might be deleted in the
// meantime. team_remove_team() acquires the thread lock when removing
// the team from the team hash table, though. Hence we switch to the
// thread lock and use mutex_lock_threads_locked().
context = (io_context*)team->io_context;
GRAB_THREAD_LOCK();
RELEASE_TEAM_LOCK();
contextLocked = mutex_lock_threads_locked(&context->io_mutex) == B_OK;
RELEASE_THREAD_LOCK();
} else
RELEASE_TEAM_LOCK();
restore_interrupts(state);
if (!contextLocked) {
// team doesn't exit or seems to be gone
// get the team
Team* team = Team::Get(teamID);
if (team == NULL)
return B_BAD_TEAM_ID;
}
BReference<Team> teamReference(team, true);
// the team cannot be deleted completely while we're owning its
// io_context mutex, so we can safely play with it now
// now that we have a team reference, its I/O context won't go away
io_context* context = team->io_context;
MutexLocker contextLocker(context->io_mutex);
uint32 slot = *_cookie;
@@ -7869,10 +7800,8 @@ _kern_get_next_fd_info(team_id teamID, uint32* _cookie, fd_info* info,
slot++;
}
if (slot >= context->table_size) {
mutex_unlock(&context->io_mutex);
if (slot >= context->table_size)
return B_ENTRY_NOT_FOUND;
}
info->number = slot;
info->open_mode = descriptor->open_mode;
@@ -7886,8 +7815,6 @@ _kern_get_next_fd_info(team_id teamID, uint32* _cookie, fd_info* info,
info->node = -1;
}
mutex_unlock(&context->io_mutex);
*_cookie = slot + 1;
return B_OK;
}