Author: tfaber
Date: Fri Oct 24 10:03:42 2014
New Revision: 64952

URL: http://svn.reactos.org/svn/reactos?rev=64952&view=rev
Log:
[NTOS:IO]
- Serialize device enumeration requests
CORE-8697 #resolve

Modified:
    trunk/reactos/ntoskrnl/include/internal/io.h
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/io.h?rev=64952&r1=64951&r2=64952&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h        [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h        [iso-8859-1] Fri Oct 24 
10:03:42 2014
@@ -1277,6 +1277,8 @@
 extern PVOID IopTriageDumpDataBlocks[64];
 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
 extern PDRIVER_OBJECT IopRootDriverObject;
+extern KSPIN_LOCK IopDeviceRelationsSpinLock;
+extern LIST_ENTRY IopDeviceRelationsRequestList;
 
 //
 // Inlined Functions

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c?rev=64952&r1=64951&r2=64952&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c  [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c  [iso-8859-1] Fri Oct 24 
10:03:42 2014
@@ -385,6 +385,8 @@
 
     /* Initialize locks and such */
     KeInitializeSpinLock(&IopDeviceTreeLock);
+    KeInitializeSpinLock(&IopDeviceRelationsSpinLock);
+    InitializeListHead(&IopDeviceRelationsRequestList);
 
     /* Get the default interface */
     PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c?rev=64952&r1=64951&r2=64952&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c   [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c   [iso-8859-1] Fri Oct 24 
10:03:42 2014
@@ -30,12 +30,16 @@
 
 PDRIVER_OBJECT IopRootDriverObject;
 PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL;
+LIST_ENTRY IopDeviceRelationsRequestList;
+WORK_QUEUE_ITEM IopDeviceRelationsWorkItem;
+BOOLEAN IopDeviceRelationsRequestInProgress;
+KSPIN_LOCK IopDeviceRelationsSpinLock;
 
 typedef struct _INVALIDATE_DEVICE_RELATION_DATA
 {
+    LIST_ENTRY RequestListEntry;
     PDEVICE_OBJECT DeviceObject;
     DEVICE_RELATION_TYPE Type;
-    PIO_WORKITEM WorkItem;
 } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
 
 /* FUNCTIONS *****************************************************************/
@@ -890,20 +894,34 @@
    return Status;
 }
 
-static VOID NTAPI
-IopAsynchronousInvalidateDeviceRelations(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID InvalidateContext)
-{
-    PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext;
-
-    IoSynchronousInvalidateDeviceRelations(
-        Data->DeviceObject,
-        Data->Type);
-
-    ObDereferenceObject(Data->DeviceObject);
-    IoFreeWorkItem(Data->WorkItem);
-    ExFreePool(Data);
+static
+VOID
+NTAPI
+IopDeviceRelationsWorker(
+    _In_ PVOID Context)
+{
+    PLIST_ENTRY ListEntry;
+    PINVALIDATE_DEVICE_RELATION_DATA Data;
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+    while (!IsListEmpty(&IopDeviceRelationsRequestList))
+    {
+        ListEntry = RemoveHeadList(&IopDeviceRelationsRequestList);
+        KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+        Data = CONTAINING_RECORD(ListEntry,
+                                 INVALIDATE_DEVICE_RELATION_DATA,
+                                 RequestListEntry);
+
+        IoSynchronousInvalidateDeviceRelations(Data->DeviceObject,
+                                               Data->Type);
+
+        ObDereferenceObject(Data->DeviceObject);
+        ExFreePool(Data);
+        KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+    }
+    IopDeviceRelationsRequestInProgress = FALSE;
+    KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
 }
 
 NTSTATUS
@@ -4670,29 +4688,32 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN DEVICE_RELATION_TYPE Type)
 {
-    PIO_WORKITEM WorkItem;
     PINVALIDATE_DEVICE_RELATION_DATA Data;
+    KIRQL OldIrql;
 
     Data = ExAllocatePool(NonPagedPool, 
sizeof(INVALIDATE_DEVICE_RELATION_DATA));
     if (!Data)
         return;
-    WorkItem = IoAllocateWorkItem(DeviceObject);
-    if (!WorkItem)
-    {
-        ExFreePool(Data);
-        return;
-    }
 
     ObReferenceObject(DeviceObject);
     Data->DeviceObject = DeviceObject;
     Data->Type = Type;
-    Data->WorkItem = WorkItem;
-
-    IoQueueWorkItem(
-        WorkItem,
-        IopAsynchronousInvalidateDeviceRelations,
-        DelayedWorkQueue,
-        Data);
+
+    KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+    InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry);
+    if (IopDeviceRelationsRequestInProgress)
+    {
+        KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+        return;
+    }
+    IopDeviceRelationsRequestInProgress = TRUE;
+    KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+
+    ExInitializeWorkItem(&IopDeviceRelationsWorkItem,
+                         IopDeviceRelationsWorker,
+                         NULL);
+    ExQueueWorkItem(&IopDeviceRelationsWorkItem,
+                    DelayedWorkQueue);
 }
 
 /*


Reply via email to