kernel: Fix deadlock with thread sending signal to itself

UserEvent can be fired from scheduler_reschedule() i.e. while holding current
thread scheduler_lock. If the current thread goes sleep and during reschedule
one of its timers sends a signel to it, then scheduler_enqueue_in_run_queue()
attempts to acquire again its scheduler_lock resulting in a deadlock.

There was also a minor issue with both scheduler_reschedule() and
scheduler_enqueue_in_run_queue() acquiring current CPU scheduler mode lock.
This commit is contained in:
Pawel Dziepak
2014-01-24 13:59:58 +01:00
parent b940183529
commit 03451e4cc1
2 changed files with 36 additions and 16 deletions
+8 -3
View File
@@ -28,11 +28,13 @@ struct UserEvent {
};
struct SignalEvent : UserEvent {
struct SignalEvent : UserEvent, private DPCCallback {
virtual ~SignalEvent();
void SetUserValue(union sigval userValue);
virtual status_t Fire();
protected:
struct EventSignal;
@@ -41,6 +43,7 @@ protected:
protected:
EventSignal* fSignal;
int32 fPendingDPC;
};
@@ -48,7 +51,8 @@ struct TeamSignalEvent : SignalEvent {
static TeamSignalEvent* Create(Team* team, uint32 signalNumber,
int32 signalCode, int32 errorCode);
virtual status_t Fire();
protected:
virtual void DoDPC(DPCQueue* queue);
private:
TeamSignalEvent(Team* team,
@@ -64,7 +68,8 @@ struct ThreadSignalEvent : SignalEvent {
int32 signalCode, int32 errorCode,
pid_t sendingTeam);
virtual status_t Fire();
protected:
virtual void DoDPC(DPCQueue* queue);
private:
ThreadSignalEvent(Thread* thread,