* 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
+5
View File
@@ -14,6 +14,10 @@
#define SIGNAL_TO_MASK(signal) (1LL << (signal - 1)) #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 #ifdef __cplusplus
extern "C" { extern "C" {
@@ -22,6 +26,7 @@ extern "C" {
extern bool handle_signals(struct thread *thread); extern bool handle_signals(struct thread *thread);
extern bool is_kill_signal_pending(void); extern bool is_kill_signal_pending(void);
extern int has_signals_pending(void *_thread); extern int has_signals_pending(void *_thread);
extern bool is_signal_blocked(int signal);
extern int sigaction_etc(thread_id threadID, int signal, extern int sigaction_etc(thread_id threadID, int signal,
const struct sigaction *newAction, struct sigaction *oldAction); const struct sigaction *newAction, struct sigaction *oldAction);
+20 -6
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. /*! 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 Interrupts must be disabled, the thread lock be held. Note, that the thread
lock may temporarily be released. 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; status_t status = B_BAD_THREAD_ID;
struct thread *thread; struct thread *thread;
cpu_status state; cpu_status state = 0;
if (signal < 0 || signal > MAX_SIGNO) if (signal < 0 || signal > MAX_SIGNO)
return B_BAD_VALUE; return B_BAD_VALUE;
state = disable_interrupts(); if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
state = disable_interrupts();
if (id > 0) { if (id > 0) {
// send a signal to the specified thread // send a signal to the specified thread
@@ -388,7 +397,8 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
} else } else
id = -id; id = -id;
GRAB_TEAM_LOCK(); if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
GRAB_TEAM_LOCK();
group = team_get_process_group_locked(NULL, id); group = team_get_process_group_locked(NULL, id);
if (group != NULL) { 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(); GRAB_THREAD_LOCK();
} }
// ToDo: maybe the scheduler should only be invoked if there is reason to do it? // 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?) // (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(); scheduler_reschedule();
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state);
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
restore_interrupts(state);
return status; return status;
} }