kernel/UserEvent: Make sure UserEvent object is valid during DPC

Most of the actual UserEvent work is done in DPC so that we don't have
to care about the limitations of the context in which UserEvent::Fire()
is invoked. This requires appropriate management of lifetime of UserEvent
instances to make sure that DoDPC() method is always called on a valid
object.
This commit is contained in:
Pawel Dziepak 2014-03-17 01:56:03 +01:00
parent dff7d3a0f2
commit d7e1e3e012
3 changed files with 12 additions and 2 deletions

View File

@ -1,4 +1,5 @@
/*
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -21,7 +22,7 @@ struct Team;
struct Thread;
struct UserEvent {
struct UserEvent : public BReferenceable {
virtual ~UserEvent();
virtual status_t Fire() = 0;

View File

@ -1,4 +1,5 @@
/*
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -87,6 +88,7 @@ SignalEvent::Fire()
return B_BUSY;
}
AcquireReference();
DPCQueue::DefaultQueue(B_NORMAL_PRIORITY)->Add(this);
return B_OK;
@ -143,6 +145,8 @@ TeamSignalEvent::DoDPC(DPCQueue* queue)
// We're no longer queued in the DPC queue, so we can be reused.
atomic_set(&fPendingDPC, 0);
ReleaseReference();
}
@ -197,6 +201,8 @@ ThreadSignalEvent::DoDPC(DPCQueue* queue)
// We're no longer queued in the DPC queue, so we can be reused.
atomic_set(&fPendingDPC, 0);
ReleaseReference();
}
@ -236,6 +242,7 @@ CreateThreadEvent::Fire()
if (wasPending)
return B_BUSY;
AcquireReference();
DPCQueue::DefaultQueue(B_NORMAL_PRIORITY)->Add(this);
return B_OK;

View File

@ -1,4 +1,5 @@
/*
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -128,7 +129,8 @@ UserTimer::UserTimer()
UserTimer::~UserTimer()
{
delete fEvent;
if (fEvent != NULL)
fEvent->ReleaseReference();
}