]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
The lock function might return an error in the case of failure. (Rev 340)
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:23:59 +0000 (12:23 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:23:59 +0000 (12:23 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@175 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

trunk/ulp/sdp/kernel/SdpLock.h
trunk/ulp/sdp/kernel/SdpSocket.cpp
trunk/ulp/sdp/kernel/SdpSocket.h

index 1eeb024ec8e564edec6c69acec1c550279cf6602..b911893215e0e8255a2a6b5dd04b2eca5677f404 100644 (file)
@@ -30,13 +30,12 @@ There will therefore be a spinlock that will protect the event.
 \r
 typedef NTSTATUS (* SendCBHandler )(SdpSocket *);\r
 typedef NTSTATUS (* RecvCBHandler )(SdpSocket *);\r
+typedef NTSTATUS (* CheckSocketStateFunction )(SdpSocket *);\r
 \r
 \r
 const int SEND_CB_CALLED        = 0x00000001;\r
 const int RECV_CB_CALLED        = 0x00000002;\r
-const int SHUTDOWN_SIGNALLED    = 0x00000004;\r
-const int SHUTDOWN_HANDELED     = 0x00000008;\r
-const int ERROR_SIGNALLED       = 0x00000010;\r
+const int ERROR_SIGNALLED       = 0x00000004;\r
 \r
 const int DPC_FLAGS = SEND_CB_CALLED | RECV_CB_CALLED;\r
 inline void ResetFlags(int &Flags)\r
@@ -55,7 +54,6 @@ inline bool SomethingToHandle(int flags)
 {\r
     if (flags & SEND_CB_CALLED) return true;\r
     if (flags & RECV_CB_CALLED) return true;\r
-    if ((flags & SHUTDOWN_SIGNALLED) && !(flags & SHUTDOWN_HANDELED) ) return true;\r
 \r
     return false;\r
 }\r
@@ -72,11 +70,17 @@ public:
         m_NumberOfClientWaiting = 0;\r
     }\r
 \r
-    VOID Init(SendCBHandler SendCB, RecvCBHandler RecvCB, SdpSocket *pSdpSocket)\r
+    VOID Init(\r
+        SendCBHandler SendCB, \r
+        RecvCBHandler RecvCB,\r
+        CheckSocketStateFunction CheckSocketState,\r
+        SdpSocket *pSdpSocket )\r
     {\r
         m_SendCBHandler = SendCB;\r
-        m_pSdpSocket = pSdpSocket;\r
+        m_CheckSocketState = CheckSocketState;\r
         m_RecvCBHandler = RecvCB;\r
+        m_pSdpSocket = pSdpSocket;\r
+        \r
     }\r
 \r
     /*\r
@@ -86,7 +90,7 @@ public:
         return value of false means that the lock can not be taken (eitheir\r
         shutdown or STATUS_ALERTED, or some error has happend)\r
     */\r
-    bool Lock() {\r
+    bool Lock(bool Force = false) {\r
         KIRQL  OldIrql;\r
         int OldFlags = 0;\r
         NTSTATUS rc = STATUS_SUCCESS;\r
@@ -107,7 +111,6 @@ public:
                 if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) {\r
                     SDP_PRINT(SDP_WARN, SDP_LOCK, ("MyKeWaitForSingleObject was alerted = 0x%x\n", rc ));\r
                     rc = STATUS_UNEXPECTED_IO_ERROR;\r
-                    SignalShutdown();\r
                     Locked = false;\r
                     goto Cleanup;\r
                 }                \r
@@ -120,14 +123,17 @@ public:
             if (WaitedOnLock) {\r
                 m_NumberOfClientWaiting--;\r
             }\r
-            ASSERT(m_NumberOfClientWaiting >= 0);\r
+            ASSERT(m_NumberOfClientWaiting >= 0);            \r
             KeReleaseSpinLock(&m_SpinLock, OldIrql);\r
             rc = HandleFlags(OldFlags);\r
-            if (!NT_SUCCESS(rc)) {\r
+            if ((Force == false) && \r
+                 (!NT_SUCCESS(rc) ||\r
+                  (m_flags & ERROR_SIGNALLED) ||\r
+                  (!NT_SUCCESS(rc = m_CheckSocketState(m_pSdpSocket)))\r
+                 )) {\r
                 // We have to signal the error to the calling side\r
                 SDP_PRINT(SDP_ERR, SDP_LOCK, ("HandleFlags failed rc = 0x%x\n", rc ));\r
                 Locked = false;\r
-                ASSERT(m_flags & ERROR_SIGNALLED);\r
                 KeAcquireSpinLock(&m_SpinLock, &OldIrql);\r
                 m_InUse = false;\r
                 // Release whoever is waiting\r
@@ -136,6 +142,7 @@ public:
                 goto Cleanup;\r
             }\r
             // Exit the loop\r
+\r
             Locked = true;\r
             goto Cleanup;            \r
         } while (true);\r
@@ -150,6 +157,8 @@ Cleanup:
         Please note that the lock is freed no metter what the error code is.\r
         An error means that there was some error in the sockets.\r
     */\r
+\r
+    //?????????? should this be ntstatus or bool ???????\r
     NTSTATUS Unlock()\r
     {\r
         KIRQL  OldIrql;\r
@@ -165,6 +174,12 @@ Cleanup:
             if (!SomethingToHandle(OldFlags)) {\r
                 // We can safely quit the lock\r
                 m_InUse = false;\r
+                // Before we leave this function we check for errors / shutdown here\r
+                if (m_flags & ERROR_SIGNALLED) {\r
+                    rc = STATUS_UNEXPECTED_IO_ERROR;\r
+                } else {\r
+                    rc = m_CheckSocketState(m_pSdpSocket);\r
+                }\r
                 KeReleaseSpinLock(&m_SpinLock, OldIrql);\r
                 break;\r
             }\r
@@ -241,7 +256,11 @@ Cleanup:
     */\r
     NTSTATUS HandleFlags(int flags) {\r
         NTSTATUS rc = STATUS_SUCCESS;\r
-        AssertLocked();\r
+        AssertLocked(); \r
+        // Try to do this faster if nothing to do\r
+        if (flags == 0) {\r
+            return STATUS_SUCCESS;\r
+        }\r
         if (flags & SEND_CB_CALLED) {\r
             // We need to handle the send CB\r
             rc = m_SendCBHandler(m_pSdpSocket);\r
@@ -265,17 +284,9 @@ Cleanup:
         return rc;\r
     }\r
 \r
-    VOID SignalShutdown() {\r
-        //??????? Verify use and correctnes\r
-        m_flags |= SHUTDOWN_SIGNALLED;\r
-    }\r
-\r
-    bool IsShutdownSignaled()\r
-    {\r
-        return m_flags & SHUTDOWN_SIGNALLED ? true : false;\r
-    }\r
-    \r
-    VOID SignalError(NTSTATUS rc) {ASSERT (FALSE);} //????????????\r
+    VOID SignalError(NTSTATUS rc) {ASSERT (FALSE);\r
+        m_flags |= ERROR_SIGNALLED;\r
+    } \r
 \r
     VOID AssertLocked() {ASSERT(m_InUse);}\r
 \r
@@ -283,6 +294,7 @@ Cleanup:
     KSPIN_LOCK  m_SpinLock; // The real guard of the lock\r
     SendCBHandler m_SendCBHandler;\r
     RecvCBHandler m_RecvCBHandler;\r
+    CheckSocketStateFunction m_CheckSocketState;\r
 \r
 \r
     bool m_InUse;           // Tells if this lock has any user\r
index d8f31d0dddd77318db42dd47cc9334324bb13aad..9d39e6cac1abff8310dfeabaa7c868f674eca933 100644 (file)
@@ -8,6 +8,7 @@ NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack);
 NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello);\r
 static NTSTATUS __send_cb2(SdpSocket * pSdpSocket);\r
 static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket);\r
+static NTSTATUS __accept_requests(SdpSocket * pSdpSocket);\r
 \r
 static void AL_API\r
 cm_rej_callback(IN ib_cm_rej_rec_t *p_cm_rej_rec )\r
@@ -144,7 +145,7 @@ NTSTATUS SdpSocket::Init(
 \r
     m_CreationFlags = pSocketInParam->dwFlags;\r
 \r
-    m_Lock.Init(__send_cb2, __recv_cb2, this);\r
+    m_Lock.Init(__send_cb2, __recv_cb2, __accept_requests ,this);\r
     pSocketOutParam->Errno = 0;// No error\r
     pSocketOutParam->pSocket = this; // give the user a handle to the socket\r
     KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE );\r
@@ -165,6 +166,15 @@ Cleanup:
     return rc;\r
 }\r
 \r
+\r
+NTSTATUS SdpSocket::AcceptRequests() \r
+{\r
+    // Check if our state allows us to handle send/recv/accept ...\r
+    if (m_ShutdownCalled) return STATUS_SHUTDOWN_IN_PROGRESS;\r
+    if (m_CloseSocketCalled) return STATUS_SHUTDOWN_IN_PROGRESS;\r
+    return STATUS_SUCCESS;\r
+}\r
+\r
 NTSTATUS SdpSocket::WSPSend(\r
         WspSendIn    *pWspSendIn,\r
         WspSendOut   *pWspSendOut\r
@@ -1056,9 +1066,11 @@ SdpSocket::WSPCloseSocket(
 \r
     }\r
 \r
-\r
-\r
     rc = m_Lock.Unlock();\r
+    if (rc == STATUS_SHUTDOWN_IN_PROGRESS) {\r
+        // shutdown in progress is fine since we have started the shutdown ...\r
+        rc = STATUS_SUCCESS;\r
+    }\r
     if (!NT_SUCCESS(rc)) {\r
         SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
         goto Cleanup;\r
@@ -1844,6 +1856,11 @@ static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket)
     return pSdpSocket->recv_cb();\r
 }\r
 \r
+static NTSTATUS __accept_requests(SdpSocket * pSdpSocket)\r
+{\r
+    return pSdpSocket->AcceptRequests();\r
+}\r
+\r
 NTSTATUS SdpSocket::send_cb()\r
 {\r
     SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("called this =0x%p\n", this));\r
@@ -2263,7 +2280,7 @@ VOID SdpSocket::Shutdown()
     }\r
     // now take the lock and test again\r
 \r
-    m_Lock.Lock();  //????????????????????force this locking ????\r
+    m_Lock.Lock(true); //????? verify must succeed\r
     if (m_ShutdownCalled) {\r
         // Already handled\r
         m_Lock.Unlock(); // Error is ignored since this is already\r
index b70706c0b77fc66d3f0ee3428f7ae7256a1919b7..28136ddfefb018c4b2e4fd97996bd21ce6dcec6e 100644 (file)
@@ -119,11 +119,7 @@ private:
     bool                    m_ShutdownCalled;\r
     bool                    m_DisconnectConnectionRecieved;\r
 \r
-    ThreadHandle*           m_pCloseSocketThread;\r
-\r
-    \r
-\r
-    VOID SignalShutdown();\r
+    ThreadHandle*           m_pCloseSocketThread;    \r
 \r
     static VOID __send_cb1(\r
         IN  const   ib_cq_handle_t  h_cq,\r
@@ -186,14 +182,7 @@ public:
 \r
     static VOID ShutdownCB(VOID* pContext);\r
 \r
-    // Make sure that lock does check this ??????????????????\r
-    bool AcceptRequests() {\r
-        // Check if our state allows us to handle send/recv/accept ...\r
-        if (m_ShutdownCalled) return false;\r
-        if (m_CloseSocketCalled) return false;\r
-        return true;\r
-    }\r
-\r
+    NTSTATUS AcceptRequests();\r
 \r
     NTSTATUS CreateQp();\r
 \r