[driver] Test stopping WvlThreadTest thread
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Tue, 4 Jan 2011 20:59:53 +0000 (15:59 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Tue, 4 Jan 2011 20:59:53 +0000 (15:59 -0500)
In WvUnload(), we add a call to a new WvTestThreadTestStop()
function (which is purely for testing).  This new function:

- Enqueues itself for WvlThreadTest.
  - Since this is the first item, WvlThreadTest is started!
- The queued item then remembers WvlThreadGetCurrent(),
  since the WvlThreadTest thread is "self-contained".
- The queued item returns control to the original call via
  an event.
- The original call now knows the "contained" thread inside
  WvlThreadTest.  Then it calls WvlThreadSendStopAndWait().
- This last call enqueues a stopper for the thread, then
  waits for the stopper signal, then waits for the thread
  to exit.  (And closes the thread handle.)

src/winvblock/driver.c

index 775523b..2b85606 100644 (file)
@@ -497,6 +497,33 @@ static NTSTATUS WvIrpPnp(
     return WvlIrpComplete(irp, 0, STATUS_NOT_SUPPORTED);
   }
 
+static WVL_F_THREAD_ITEM WvTestThreadTestStop;
+static VOID STDCALL WvTestThreadTestStop(IN OUT WVL_SP_THREAD_ITEM item) {
+    static WVL_S_THREAD_ITEM stopper = { {0}, WvTestThreadTestStop };
+    static WVL_SP_THREAD thread = NULL;
+    static KEVENT event;
+
+    /* If we have an item, we're in the thread.  Remember it. */
+    if (item) {
+        thread = WvlThreadGetCurrent();
+        KeSetEvent(&event, 0, FALSE);
+        return;
+      }
+    /* Otherwise, enqueue ourself. */
+    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
+    WvlThreadTest(&stopper);
+    KeWaitForSingleObject(
+        &event,
+        Executive,
+        KernelMode,
+        FALSE,
+        NULL
+      );
+    /* Now we should know the thread.  Stop it and wait. */
+    WvlThreadSendStopAndWait(thread);
+    return;
+  }
+
 static VOID STDCALL WvUnload(IN PDRIVER_OBJECT DriverObject) {
     DBG("Unloading...\n");
     WvBus.Stop = TRUE;
@@ -511,6 +538,7 @@ static VOID STDCALL WvUnload(IN PDRIVER_OBJECT DriverObject) {
           );
         ObDereferenceObject(WvBusThread);
       }
+    WvTestThreadTestStop(NULL);
     if (WvDriverStateHandle != NULL)
       PoUnregisterSystemState(WvDriverStateHandle);
     IoDeleteSymbolicLink(&WvBusDosname);