]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
libibverbs/comp_mgr: fix hang during destruction
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 5 Aug 2009 23:43:36 +0000 (23:43 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 5 Aug 2009 23:43:36 +0000 (23:43 +0000)
The completion manager abstraction can hang during cleanup.  The hang
occurs when the user calls CompManagerCancel before calling CompManagerClose,
and the user is not waiting for events.  In this case, the completion manager
thread will pull the cancel request from the IO completion port and queue it
with the manager.  When CompManagerClose is called, it calls CompManagerCancel
to signal the thread to check the running state.  However, the completion
manager's event structure is still marked busy from the user's CompManagerCancel
call.

The result is that the completion manager thread does not receive the
signal to check the running flag and remains asleep.  Fix this by using a
different completion entry to signal the thread during destruction than that
used to cancel a CompManagerPoll event.

This fixes occasional hangs running dapltest with both the rdma_cm and socket
cm providers.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2330 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/winverbs/etc/user/comp_channel.cpp

index 8b91d6cbac2e1f01b7b1c75b6bd7c3ea61cfe1ca..ca3356e17efe93012856a2a61cdeadfda9fefcd0 100644 (file)
@@ -102,8 +102,12 @@ err1:
 \r
 void CompManagerClose(COMP_MANAGER *pMgr)\r
 {\r
+       COMP_CHANNEL *channel;\r
+       COMP_ENTRY entry;\r
+\r
        pMgr->Run = FALSE;\r
-       CompManagerCancel(pMgr);\r
+       CompEntryInit(NULL, &entry);\r
+       PostQueuedCompletionStatus(pMgr->CompQueue, 0, (ULONG_PTR) pMgr, &entry.Overlap);\r
        WaitForSingleObject(pMgr->Thread, INFINITE);\r
        CloseHandle(pMgr->Thread);\r
 \r
@@ -318,12 +322,7 @@ COMP_ENTRY *CompEntryCancel(COMP_ENTRY *pEntry)
 \r
        while (pEntry->Busy) {\r
                Sleep(0);\r
-               if (((ULONG_PTR) pEntry->Overlap.hEvent) & 1) {\r
-                       pEntry->Busy = !HasOverlappedIoCompleted(&pEntry->Overlap);\r
-                       entry = pEntry;\r
-               } else {\r
-                       entry = CompChannelFindRemove(pEntry->Channel, pEntry);\r
-               }\r
+               entry = CompChannelFindRemove(pEntry->Channel, pEntry);\r
        }\r
        return entry;\r
 }\r