Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
4.8 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: connection.cpp
  6. * Content: Connection routines
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 10/13/99 mjn Created
  12. * 03/02/00 mjn Conversion to class
  13. * 04/08/00 mjn Added ServiceProvider to Connection object
  14. * mjn Disconnect uses new CAsyncOp class
  15. * 04/18/00 mjn CConnection tracks connection status better
  16. * 04/21/00 mjn Disconnection through DNPerformDisconnect
  17. * 07/20/00 mjn Changed Release() behaviour and beefed up Disconnect()
  18. * 07/28/00 mjn Added m_bilinkConnections to CConnection
  19. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  20. * 02/12/01 mjn Fixed CConnection::GetEndPt() to track calling thread and added ReleaseEndPt()
  21. * 04/04/01 mjn CConnection list off DirectNetObject guarded by proper critical section
  22. *@@END_MSINTERNAL
  23. *
  24. ***************************************************************************/
  25. #include "dncorei.h"
  26. // CConnection::ReturnSelfToPool
  27. //
  28. // Return object to FPM
  29. #undef DPF_MODNAME
  30. #define DPF_MODNAME "CConnection::ReturnSelfToPool"
  31. void CConnection::ReturnSelfToPool( void )
  32. {
  33. DPFX(DPFPREP, 8,"Parameters: (none)");
  34. g_ConnectionPool.Release( this );
  35. DPFX(DPFPREP, 8,"Returning");
  36. };
  37. #undef DPF_MODNAME
  38. #define DPF_MODNAME "CConnection::Release"
  39. void CConnection::Release(void)
  40. {
  41. LONG lRefCount;
  42. DPFX(DPFPREP, 8,"Parameters: (none)");
  43. DNASSERT(m_lRefCount > 0);
  44. lRefCount = DNInterlockedDecrement(const_cast<LONG*>(&m_lRefCount));
  45. DPFX(DPFPREP, 3,"Connection::Release [0x%p] RefCount [0x%lx]",this,lRefCount);
  46. if (lRefCount == 0)
  47. {
  48. //
  49. // Remove from the bilink of outstanding CConnection objects
  50. //
  51. DNEnterCriticalSection(&m_pdnObject->csConnectionList);
  52. m_bilinkConnections.RemoveFromList();
  53. DNLeaveCriticalSection(&m_pdnObject->csConnectionList);
  54. if (m_pSP)
  55. {
  56. m_pSP->Release();
  57. m_pSP = NULL;
  58. }
  59. m_dwFlags = 0;
  60. m_lRefCount = 0;
  61. m_hEndPt = NULL;
  62. ReturnSelfToPool();
  63. }
  64. DPFX(DPFPREP, 8,"Returning");
  65. };
  66. #undef DPF_MODNAME
  67. #define DPF_MODNAME "CConnection::GetEndPt"
  68. HRESULT CConnection::GetEndPt(HANDLE *const phEndPt,CCallbackThread *const pCallbackThread)
  69. {
  70. HRESULT hResultCode;
  71. DNASSERT(phEndPt != NULL);
  72. DNASSERT(pCallbackThread != NULL);
  73. Lock();
  74. if ((m_Status == CONNECTED) || (m_Status == CONNECTING))
  75. {
  76. //
  77. // Add the calling thread to the bilink to that the endpoint will
  78. // not be invalidated (through IndicateConnectionTerminated) until
  79. // this thread is done with the endpoint.
  80. //
  81. pCallbackThread->GetCallbackThreadsBilink()->InsertBefore(&m_bilinkCallbackThreads);
  82. *phEndPt = m_hEndPt;
  83. hResultCode = DPN_OK;
  84. }
  85. else
  86. {
  87. hResultCode = DPNERR_NOCONNECTION;
  88. }
  89. Unlock();
  90. return(hResultCode);
  91. };
  92. #undef DPF_MODNAME
  93. #define DPF_MODNAME "CConnection::ReleaseEndPt"
  94. void CConnection::ReleaseEndPt(CCallbackThread *const pCallbackThread)
  95. {
  96. DNASSERT(pCallbackThread != NULL);
  97. Lock();
  98. pCallbackThread->GetCallbackThreadsBilink()->RemoveFromList();
  99. if (m_dwThreadCount != 0)
  100. {
  101. //
  102. // If there is a thread count,
  103. // decrement it
  104. // if this is the last count
  105. // set the event
  106. //
  107. m_dwThreadCount--;
  108. if (m_dwThreadCount == 0)
  109. {
  110. DNASSERT(m_pThreadEvent != NULL);
  111. if (m_pThreadEvent)
  112. {
  113. m_pThreadEvent->Set();
  114. }
  115. }
  116. }
  117. Unlock();
  118. }
  119. #undef DPF_MODNAME
  120. #define DPF_MODNAME "CConnection::SetSP"
  121. void CConnection::SetSP( CServiceProvider *const pSP )
  122. {
  123. DPFX(DPFPREP, 8,"Parameters: pSP [0x%p]",pSP);
  124. DNASSERT( pSP != NULL );
  125. pSP->AddRef();
  126. m_pSP = pSP;
  127. DPFX(DPFPREP, 8,"Returning");
  128. }
  129. // CConnection::Disconnect
  130. //
  131. // Initiate a disconnection. If this is successful, eventually we will receive an IndicateConnectionTerminated
  132. // which we should use to remove a reference (from the Protocol).
  133. #undef DPF_MODNAME
  134. #define DPF_MODNAME "CConnection::Disconnect"
  135. void CConnection::Disconnect( void )
  136. {
  137. BOOL fDisconnect;
  138. DPFX(DPFPREP, 8,"Parameters: (none)");
  139. DNASSERT(m_pdnObject != NULL);
  140. fDisconnect = FALSE;
  141. Lock();
  142. if ((m_Status == CONNECTING) || (m_Status == CONNECTED))
  143. {
  144. if (m_hEndPt != NULL)
  145. {
  146. m_Status = DISCONNECTING;
  147. fDisconnect = TRUE;
  148. }
  149. else
  150. {
  151. m_Status = INVALID;
  152. }
  153. }
  154. Unlock();
  155. if (fDisconnect)
  156. {
  157. #ifndef DPNBUILD_NOMULTICAST
  158. if (m_dwFlags & CONNECTION_FLAG_MULTICAST_RECEIVER)
  159. {
  160. DNUserDestroySenderContext(m_pdnObject,m_pvContext);
  161. }
  162. #endif // DPNBUILD_NOMULTICAST
  163. DNPerformDisconnect(m_pdnObject,this,m_hEndPt,FALSE);
  164. }
  165. DPFX(DPFPREP, 8,"Returning");
  166. }