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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user