- Fix race condition for status change worker routine
CORE-7193 #resolve
- Tested by Thomas Faber (Blame him ;)

svn path=/trunk/; revision=59039
This commit is contained in:
Johannes Anderwald 2013-05-18 20:16:50 +00:00
parent bbf97892df
commit b07d7ec92a
2 changed files with 24 additions and 14 deletions

View file

@ -96,7 +96,7 @@ protected:
PVOID m_SCEContext; // status change callback routine context
BOOLEAN m_DoorBellRingInProgress; // door bell ring in progress
WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
ULONG m_WorkItemActive; // work item status
volatile LONG m_StatusChangeWorkItemStatus; // work item status
ULONG m_SyncFramePhysAddr; // periodic frame list physical address
BUS_INTERFACE_STANDARD m_BusInterface; // pci bus interface
BOOLEAN m_PortResetInProgress[0xF]; // stores reset in progress (vbox hack)
@ -1433,13 +1433,13 @@ EhciDefferedRoutine(
//
if (QueueSCEWorkItem && This->m_SCECallBack != NULL)
{
// work item is now active
This->m_WorkItemActive = TRUE;
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
}
return;
@ -1466,8 +1466,10 @@ StatusChangeWorkItemRoutine(
This->m_SCECallBack(This->m_SCEContext);
}
// work item is completed
This->m_WorkItemActive = FALSE;
//
// reset active status
//
InterlockedDecrement(&This->m_StatusChangeWorkItemStatus);
}
NTSTATUS

View file

@ -101,6 +101,7 @@ protected:
HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine
PVOID m_SCEContext; // status change callback routine context
WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
volatile LONG m_StatusChangeWorkItemStatus; // work item active status
ULONG m_SyncFramePhysAddr; // periodic frame list physical address
ULONG m_IntervalValue; // periodic interval value
};
@ -1523,10 +1524,13 @@ OhciDefferedRoutine(
//
if (QueueSCEWorkItem && This->m_SCECallBack != NULL)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
}
}
@ -1552,6 +1556,10 @@ StatusChangeWorkItemRoutine(
This->m_SCECallBack(This->m_SCEContext);
}
//
// reset active status
//
InterlockedDecrement(&This->m_StatusChangeWorkItemStatus);
}
NTSTATUS