* Added is_signal_blocked() convenience function.

* Defined flag SIGNAL_FLAG_TEAMS_LOCKED for send_signal_etc(), so it can
  be called with the team lock being held.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22186 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-09-06 02:03:43 +00:00
parent 35e78b5674
commit df716df51d
2 changed files with 25 additions and 6 deletions

View File

@ -14,6 +14,10 @@
#define SIGNAL_TO_MASK(signal) (1LL << (signal - 1))
// additional send_signal_etc() flag
#define SIGNAL_FLAG_TEAMS_LOCKED (0x10000)
// interrupts are disabled and team lock is held
#ifdef __cplusplus
extern "C" {
@ -22,6 +26,7 @@ extern "C" {
extern bool handle_signals(struct thread *thread);
extern bool is_kill_signal_pending(void);
extern int has_signals_pending(void *_thread);
extern bool is_signal_blocked(int signal);
extern int sigaction_etc(thread_id threadID, int signal,
const struct sigaction *newAction, struct sigaction *oldAction);

View File

@ -265,6 +265,14 @@ is_kill_signal_pending(void)
}
bool
is_signal_blocked(int signal)
{
return (atomic_get(&thread_get_current_thread()->sig_block_mask)
& SIGNAL_TO_MASK(signal)) != 0;
}
/*! Tries to interrupt a thread waiting for a semaphore or a condition variable.
Interrupts must be disabled, the thread lock be held. Note, that the thread
lock may temporarily be released.
@ -360,12 +368,13 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
{
status_t status = B_BAD_THREAD_ID;
struct thread *thread;
cpu_status state;
cpu_status state = 0;
if (signal < 0 || signal > MAX_SIGNO)
return B_BAD_VALUE;
state = disable_interrupts();
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
state = disable_interrupts();
if (id > 0) {
// send a signal to the specified thread
@ -388,7 +397,8 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
} else
id = -id;
GRAB_TEAM_LOCK();
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
GRAB_TEAM_LOCK();
group = team_get_process_group_locked(NULL, id);
if (group != NULL) {
@ -413,17 +423,21 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
}
}
RELEASE_TEAM_LOCK();
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
RELEASE_TEAM_LOCK();
GRAB_THREAD_LOCK();
}
// ToDo: maybe the scheduler should only be invoked if there is reason to do it?
// (ie. deliver_signal() moved some threads in the running queue?)
if ((flags & B_DO_NOT_RESCHEDULE) == 0)
if ((flags & (B_DO_NOT_RESCHEDULE | SIGNAL_FLAG_TEAMS_LOCKED)) == 0)
scheduler_reschedule();
RELEASE_THREAD_LOCK();
restore_interrupts(state);
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
restore_interrupts(state);
return status;
}