Index: core/winverbs/kernel/wv_ep.c
===================================================================
--- core/winverbs/kernel/wv_ep.c	(revision 2373)
+++ core/winverbs/kernel/wv_ep.c	(working copy)
@@ -181,6 +181,9 @@
 
 void WvEpFree(WV_ENDPOINT *pEndpoint)
 {
+	// see comment in WvEpProcessAsync()
+	// WorkQueueFlush(&pEndpoint->pProvider->WorkQueue);
+
 	if (pEndpoint->pIbCmId != NULL) {
 		IbCmInterface.CM.destroy_id(pEndpoint->pIbCmId);
 	}
@@ -644,7 +647,18 @@
 
 	work = WorkEntryFromIrp(WdfRequestWdmGetIrp(Request));
 	WorkEntryInit(work, AsyncHandler, Request);
-	WorkQueueInsert(&pProvider->WorkQueue, work);
+	// TODO: If app exits or crashes immediately after making a CM call,
+	// then WvEpFree() will be called, which destroys
+	// the pIbCmId.  Since the IRP is not on a queue, the system cannot
+	// cancel the operation.  If the work queue thread is running, this can
+	// result in it accessing the pIbCmId after it is destroyed.
+	// The fix for this is to call 'WorkQueueFlush()' from WvEpFree() to
+	// ensure that the EP's work entry is not in use and all previous
+	// IRPs have completed before the pIbCmId is destroyed.
+	// Until WorkQueueFlush is available, continue to process Connect
+	// and Accept calls synchronously.
+	//WorkQueueInsert(&pProvider->WorkQueue, work);
+	AsyncHandler(work);
 }
 
 void WvEpConnect(WV_PROVIDER *pProvider, WDFREQUEST Request)
