From: tzachid Date: Mon, 21 Nov 2005 12:23:59 +0000 (+0000) Subject: The lock function might return an error in the case of failure. (Rev 340) X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=89ceff63ef5769173e240b6df32575a2614ea1de;p=~shefty%2Frdma-win.git The lock function might return an error in the case of failure. (Rev 340) git-svn-id: svn://openib.tc.cornell.edu/gen1@175 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/ulp/sdp/kernel/SdpLock.h b/trunk/ulp/sdp/kernel/SdpLock.h index 1eeb024e..b9118932 100644 --- a/trunk/ulp/sdp/kernel/SdpLock.h +++ b/trunk/ulp/sdp/kernel/SdpLock.h @@ -30,13 +30,12 @@ There will therefore be a spinlock that will protect the event. typedef NTSTATUS (* SendCBHandler )(SdpSocket *); typedef NTSTATUS (* RecvCBHandler )(SdpSocket *); +typedef NTSTATUS (* CheckSocketStateFunction )(SdpSocket *); const int SEND_CB_CALLED = 0x00000001; const int RECV_CB_CALLED = 0x00000002; -const int SHUTDOWN_SIGNALLED = 0x00000004; -const int SHUTDOWN_HANDELED = 0x00000008; -const int ERROR_SIGNALLED = 0x00000010; +const int ERROR_SIGNALLED = 0x00000004; const int DPC_FLAGS = SEND_CB_CALLED | RECV_CB_CALLED; inline void ResetFlags(int &Flags) @@ -55,7 +54,6 @@ inline bool SomethingToHandle(int flags) { if (flags & SEND_CB_CALLED) return true; if (flags & RECV_CB_CALLED) return true; - if ((flags & SHUTDOWN_SIGNALLED) && !(flags & SHUTDOWN_HANDELED) ) return true; return false; } @@ -72,11 +70,17 @@ public: m_NumberOfClientWaiting = 0; } - VOID Init(SendCBHandler SendCB, RecvCBHandler RecvCB, SdpSocket *pSdpSocket) + VOID Init( + SendCBHandler SendCB, + RecvCBHandler RecvCB, + CheckSocketStateFunction CheckSocketState, + SdpSocket *pSdpSocket ) { m_SendCBHandler = SendCB; - m_pSdpSocket = pSdpSocket; + m_CheckSocketState = CheckSocketState; m_RecvCBHandler = RecvCB; + m_pSdpSocket = pSdpSocket; + } /* @@ -86,7 +90,7 @@ public: return value of false means that the lock can not be taken (eitheir shutdown or STATUS_ALERTED, or some error has happend) */ - bool Lock() { + bool Lock(bool Force = false) { KIRQL OldIrql; int OldFlags = 0; NTSTATUS rc = STATUS_SUCCESS; @@ -107,7 +111,6 @@ public: if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) { SDP_PRINT(SDP_WARN, SDP_LOCK, ("MyKeWaitForSingleObject was alerted = 0x%x\n", rc )); rc = STATUS_UNEXPECTED_IO_ERROR; - SignalShutdown(); Locked = false; goto Cleanup; } @@ -120,14 +123,17 @@ public: if (WaitedOnLock) { m_NumberOfClientWaiting--; } - ASSERT(m_NumberOfClientWaiting >= 0); + ASSERT(m_NumberOfClientWaiting >= 0); KeReleaseSpinLock(&m_SpinLock, OldIrql); rc = HandleFlags(OldFlags); - if (!NT_SUCCESS(rc)) { + if ((Force == false) && + (!NT_SUCCESS(rc) || + (m_flags & ERROR_SIGNALLED) || + (!NT_SUCCESS(rc = m_CheckSocketState(m_pSdpSocket))) + )) { // We have to signal the error to the calling side SDP_PRINT(SDP_ERR, SDP_LOCK, ("HandleFlags failed rc = 0x%x\n", rc )); Locked = false; - ASSERT(m_flags & ERROR_SIGNALLED); KeAcquireSpinLock(&m_SpinLock, &OldIrql); m_InUse = false; // Release whoever is waiting @@ -136,6 +142,7 @@ public: goto Cleanup; } // Exit the loop + Locked = true; goto Cleanup; } while (true); @@ -150,6 +157,8 @@ Cleanup: Please note that the lock is freed no metter what the error code is. An error means that there was some error in the sockets. */ + + //?????????? should this be ntstatus or bool ??????? NTSTATUS Unlock() { KIRQL OldIrql; @@ -165,6 +174,12 @@ Cleanup: if (!SomethingToHandle(OldFlags)) { // We can safely quit the lock m_InUse = false; + // Before we leave this function we check for errors / shutdown here + if (m_flags & ERROR_SIGNALLED) { + rc = STATUS_UNEXPECTED_IO_ERROR; + } else { + rc = m_CheckSocketState(m_pSdpSocket); + } KeReleaseSpinLock(&m_SpinLock, OldIrql); break; } @@ -241,7 +256,11 @@ Cleanup: */ NTSTATUS HandleFlags(int flags) { NTSTATUS rc = STATUS_SUCCESS; - AssertLocked(); + AssertLocked(); + // Try to do this faster if nothing to do + if (flags == 0) { + return STATUS_SUCCESS; + } if (flags & SEND_CB_CALLED) { // We need to handle the send CB rc = m_SendCBHandler(m_pSdpSocket); @@ -265,17 +284,9 @@ Cleanup: return rc; } - VOID SignalShutdown() { - //??????? Verify use and correctnes - m_flags |= SHUTDOWN_SIGNALLED; - } - - bool IsShutdownSignaled() - { - return m_flags & SHUTDOWN_SIGNALLED ? true : false; - } - - VOID SignalError(NTSTATUS rc) {ASSERT (FALSE);} //???????????? + VOID SignalError(NTSTATUS rc) {ASSERT (FALSE); + m_flags |= ERROR_SIGNALLED; + } VOID AssertLocked() {ASSERT(m_InUse);} @@ -283,6 +294,7 @@ Cleanup: KSPIN_LOCK m_SpinLock; // The real guard of the lock SendCBHandler m_SendCBHandler; RecvCBHandler m_RecvCBHandler; + CheckSocketStateFunction m_CheckSocketState; bool m_InUse; // Tells if this lock has any user diff --git a/trunk/ulp/sdp/kernel/SdpSocket.cpp b/trunk/ulp/sdp/kernel/SdpSocket.cpp index d8f31d0d..9d39e6ca 100644 --- a/trunk/ulp/sdp/kernel/SdpSocket.cpp +++ b/trunk/ulp/sdp/kernel/SdpSocket.cpp @@ -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); static NTSTATUS __send_cb2(SdpSocket * pSdpSocket); static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket); +static NTSTATUS __accept_requests(SdpSocket * pSdpSocket); static void AL_API cm_rej_callback(IN ib_cm_rej_rec_t *p_cm_rej_rec ) @@ -144,7 +145,7 @@ NTSTATUS SdpSocket::Init( m_CreationFlags = pSocketInParam->dwFlags; - m_Lock.Init(__send_cb2, __recv_cb2, this); + m_Lock.Init(__send_cb2, __recv_cb2, __accept_requests ,this); pSocketOutParam->Errno = 0;// No error pSocketOutParam->pSocket = this; // give the user a handle to the socket KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE ); @@ -165,6 +166,15 @@ Cleanup: return rc; } + +NTSTATUS SdpSocket::AcceptRequests() +{ + // Check if our state allows us to handle send/recv/accept ... + if (m_ShutdownCalled) return STATUS_SHUTDOWN_IN_PROGRESS; + if (m_CloseSocketCalled) return STATUS_SHUTDOWN_IN_PROGRESS; + return STATUS_SUCCESS; +} + NTSTATUS SdpSocket::WSPSend( WspSendIn *pWspSendIn, WspSendOut *pWspSendOut @@ -1056,9 +1066,11 @@ SdpSocket::WSPCloseSocket( } - - rc = m_Lock.Unlock(); + if (rc == STATUS_SHUTDOWN_IN_PROGRESS) { + // shutdown in progress is fine since we have started the shutdown ... + rc = STATUS_SUCCESS; + } if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc )); goto Cleanup; @@ -1844,6 +1856,11 @@ static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket) return pSdpSocket->recv_cb(); } +static NTSTATUS __accept_requests(SdpSocket * pSdpSocket) +{ + return pSdpSocket->AcceptRequests(); +} + NTSTATUS SdpSocket::send_cb() { SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("called this =0x%p\n", this)); @@ -2263,7 +2280,7 @@ VOID SdpSocket::Shutdown() } // now take the lock and test again - m_Lock.Lock(); //????????????????????force this locking ???? + m_Lock.Lock(true); //????? verify must succeed if (m_ShutdownCalled) { // Already handled m_Lock.Unlock(); // Error is ignored since this is already diff --git a/trunk/ulp/sdp/kernel/SdpSocket.h b/trunk/ulp/sdp/kernel/SdpSocket.h index b70706c0..28136ddf 100644 --- a/trunk/ulp/sdp/kernel/SdpSocket.h +++ b/trunk/ulp/sdp/kernel/SdpSocket.h @@ -119,11 +119,7 @@ private: bool m_ShutdownCalled; bool m_DisconnectConnectionRecieved; - ThreadHandle* m_pCloseSocketThread; - - - - VOID SignalShutdown(); + ThreadHandle* m_pCloseSocketThread; static VOID __send_cb1( IN const ib_cq_handle_t h_cq, @@ -186,14 +182,7 @@ public: static VOID ShutdownCB(VOID* pContext); - // Make sure that lock does check this ?????????????????? - bool AcceptRequests() { - // Check if our state allows us to handle send/recv/accept ... - if (m_ShutdownCalled) return false; - if (m_CloseSocketCalled) return false; - return true; - } - + NTSTATUS AcceptRequests(); NTSTATUS CreateQp();