datapath-windows: Avoid BSOD when no event queue found.
[cascardo/ovs.git] / datapath-windows / ovsext / Event.c
index fec3485..d38bc70 100644 (file)
@@ -16,8 +16,9 @@
 
 #include "precomp.h"
 
-#include "Datapath.h"
 #include "Switch.h"
+#include "User.h"
+#include "Datapath.h"
 #include "Vport.h"
 #include "Event.h"
 
 #include "Debug.h"
 
 LIST_ENTRY ovsEventQueue;
+static NDIS_SPIN_LOCK eventQueueLock;
 UINT32 ovsNumEventQueue;
 UINT32 ovsNumPollAll;
 
-extern PNDIS_SPIN_LOCK gOvsCtrlLock;
-
 NTSTATUS
 OvsInitEventQueue()
 {
     InitializeListHead(&ovsEventQueue);
+    NdisAllocateSpinLock(&eventQueueLock);
     return STATUS_SUCCESS;
 }
 
@@ -45,18 +46,19 @@ OvsCleanupEventQueue()
 {
     ASSERT(IsListEmpty(&ovsEventQueue));
     ASSERT(ovsNumEventQueue == 0);
+    NdisFreeSpinLock(&eventQueueLock);
 }
 
 static __inline VOID
 OvsAcquireEventQueueLock()
 {
-    NdisAcquireSpinLock(gOvsCtrlLock);
+    NdisAcquireSpinLock(&eventQueueLock);
 }
 
 static __inline VOID
 OvsReleaseEventQueueLock()
 {
-   NdisReleaseSpinLock(gOvsCtrlLock);
+   NdisReleaseSpinLock(&eventQueueLock);
 }
 
 /*
@@ -292,6 +294,7 @@ done_event_subscribe:
     return status;
 }
 
+#if defined OVS_USE_NL_INTERFACE && OVS_USE_NL_INTERFACE == 0
 /*
  * --------------------------------------------------------------------------
  * Poll event queued in the event queue. always synchronous.
@@ -376,6 +379,7 @@ event_poll_done:
     OVS_LOG_TRACE("Exit: numEventPolled: %d", numEntry);
     return STATUS_SUCCESS;
 }
+#endif /* OVS_USE_NL_INTERFACE */
 
 
 /*
@@ -465,6 +469,11 @@ OvsWaitEventIoctl(PIRP irp,
     }
 
     queue = (POVS_EVENT_QUEUE)instance->eventQueue;
+    if (queue == NULL) {
+        OvsReleaseEventQueueLock();
+        OVS_LOG_TRACE("Exit: Event queue does not exist");
+        return STATUS_INVALID_PARAMETER;
+    }
     if (queue->pendingIrp) {
         OvsReleaseEventQueueLock();
         OVS_LOG_TRACE("Exit: Event queue already in pending state");
@@ -494,3 +503,43 @@ OvsWaitEventIoctl(PIRP irp,
     OVS_LOG_TRACE("Exit: return status: %#x", status);
     return status;
 }
+
+/*
+ *--------------------------------------------------------------------------
+ * Poll event queued in the event queue.always synchronous.
+ *
+ * Results:
+ *     STATUS_SUCCESS event was dequeued
+ *     STATUS_UNSUCCESSFUL the queue is empty.
+ * --------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsRemoveEventEntry(POVS_OPEN_INSTANCE instance,
+                    POVS_EVENT_ENTRY entry)
+{
+    NTSTATUS status = STATUS_UNSUCCESSFUL;
+    POVS_EVENT_QUEUE queue;
+    POVS_EVENT_QUEUE_ELEM elem;
+
+    OvsAcquireEventQueueLock();
+
+    queue = (POVS_EVENT_QUEUE)instance->eventQueue;
+
+    if (queue == NULL) {
+        ASSERT(queue);
+        goto remove_event_done;
+    }
+
+    if (queue->numElems) {
+        elem = (POVS_EVENT_QUEUE_ELEM)RemoveHeadList(&queue->elemList);
+        entry->portNo = elem->portNo;
+        entry->status = elem->status;
+        OvsFreeMemory(elem);
+        queue->numElems--;
+        status = STATUS_SUCCESS;
+    }
+
+remove_event_done:
+    OvsReleaseEventQueueLock();
+    return status;
+}