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.

167 lines
5.1 KiB

  1. /************************************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. File Name: SocketPool.cpp
  4. Abstract: Implementation of the socket pool (CSocketPool class)
  5. and the callback function for IO Context.
  6. Notes:
  7. History: 08/01/2001 Created by Hao Yu (haoyu)
  8. ************************************************************************************************/
  9. #include "stdafx.h"
  10. #include <IOLists.h>
  11. #include "POP3Context.h"
  12. CIOList::CIOList()
  13. {
  14. InitializeCriticalSection(&m_csListGuard);
  15. m_dwListCount=0;
  16. m_ListHead.Flink=&m_ListHead;
  17. m_ListHead.Blink=&m_ListHead;
  18. m_pCursor=&m_ListHead;
  19. }
  20. CIOList::~CIOList()
  21. {
  22. DeleteCriticalSection(&m_csListGuard);
  23. }
  24. void CIOList::AppendToList(PLIST_ENTRY pListEntry)
  25. {
  26. ASSERT(NULL != pListEntry);
  27. EnterCriticalSection(&m_csListGuard);
  28. pListEntry->Flink=&m_ListHead;
  29. pListEntry->Blink=m_ListHead.Blink;
  30. m_ListHead.Blink->Flink=pListEntry;
  31. m_ListHead.Blink=pListEntry;
  32. m_dwListCount++;
  33. LeaveCriticalSection(&m_csListGuard);
  34. }
  35. DWORD CIOList::RemoveFromList(PLIST_ENTRY pListEntry)
  36. {
  37. if( (NULL == pListEntry) ||
  38. (NULL == pListEntry->Flink) ||
  39. (NULL == pListEntry->Blink) ||
  40. (m_dwListCount ==0) )
  41. {
  42. return ERROR_INVALID_DATA;
  43. }
  44. EnterCriticalSection(&m_csListGuard);
  45. pListEntry->Flink->Blink=pListEntry->Blink;
  46. pListEntry->Blink->Flink=pListEntry->Flink;
  47. m_dwListCount--;
  48. //In case the Timeout checking is on going.
  49. if(m_pCursor == pListEntry)
  50. {
  51. m_pCursor = pListEntry->Flink;
  52. }
  53. pListEntry->Flink=NULL;
  54. pListEntry->Blink=NULL;
  55. LeaveCriticalSection(&m_csListGuard);
  56. return ERROR_SUCCESS;
  57. }
  58. // Returns the waiting time of the socket that waited the longest
  59. // but not yet timed out.
  60. DWORD CIOList::CheckTimeOut(DWORD dwTimeOutInterval,BOOL *pbIsAnyOneTimedOut)
  61. {
  62. DWORD dwTime;
  63. DWORD dwNextTimeOut=0;
  64. DWORD dwTimeOut=0;
  65. PIO_CONTEXT pIoContext;
  66. m_pCursor=m_ListHead.Flink;
  67. while(m_pCursor!=&m_ListHead)
  68. {
  69. EnterCriticalSection(&m_csListGuard);
  70. if(m_pCursor==&m_ListHead)
  71. {
  72. LeaveCriticalSection(&m_csListGuard);
  73. break;
  74. }
  75. pIoContext=CONTAINING_RECORD(m_pCursor, IO_CONTEXT, m_ListEntry);
  76. ASSERT(NULL != pIoContext);
  77. if( UNLOCKED==InterlockedCompareExchange(&(pIoContext->m_lLock),LOCKED_FOR_TIMEOUT, UNLOCKED) )
  78. {
  79. if(DELETE_PENDING!=pIoContext->m_ConType)
  80. {
  81. dwTime=GetTickCount();
  82. if(dwTime > pIoContext->m_dwLastIOTime )
  83. {
  84. dwTimeOut=dwTime - pIoContext->m_dwLastIOTime;
  85. }
  86. else
  87. {
  88. dwTimeOut=0;
  89. }
  90. if( ( dwTimeOut >= DEFAULT_TIME_OUT) || // Normal time out
  91. ( ( dwTimeOut >= dwTimeOutInterval) && // DoS Time out
  92. ( dwTimeOutInterval == SHORTENED_TIMEOUT) &&
  93. ( pIoContext->m_pPop3Context->Unauthenticated()) ) )
  94. {
  95. //This IO timed out
  96. ASSERT(NULL != pIoContext->m_pPop3Context);
  97. m_pCursor=m_pCursor->Flink;
  98. pIoContext->m_pPop3Context->TimeOut(pIoContext);
  99. if(pbIsAnyOneTimedOut)
  100. *pbIsAnyOneTimedOut=TRUE;
  101. }
  102. else
  103. {
  104. if(dwNextTimeOut<dwTimeOut)
  105. {
  106. dwNextTimeOut=dwTimeOut;
  107. }
  108. m_pCursor=m_pCursor->Flink;
  109. }
  110. }
  111. else
  112. {
  113. m_pCursor=m_pCursor->Flink;
  114. }
  115. InterlockedExchange(&(pIoContext->m_lLock),UNLOCKED);
  116. }
  117. else
  118. {
  119. m_pCursor=m_pCursor->Flink;
  120. }
  121. //Leave Critical Section so that other
  122. //threads will get a chance to run.
  123. LeaveCriticalSection(&m_csListGuard);
  124. }
  125. return dwNextTimeOut;
  126. }
  127. void CIOList::Cleanup()
  128. {
  129. PLIST_ENTRY pCursor=m_ListHead.Flink;
  130. PIO_CONTEXT pIoContext;
  131. EnterCriticalSection(&m_csListGuard);
  132. while(pCursor!=&m_ListHead)
  133. {
  134. pIoContext=CONTAINING_RECORD(pCursor, IO_CONTEXT, m_ListEntry);
  135. ASSERT(NULL != pIoContext);
  136. ASSERT(NULL != pIoContext->m_pPop3Context);
  137. pIoContext->m_pPop3Context->TimeOut(pIoContext);
  138. pCursor->Flink->Blink=pCursor->Blink;
  139. pCursor->Blink->Flink=pCursor->Flink;
  140. pCursor=pCursor->Flink;
  141. ASSERT(m_dwListCount >= 1);
  142. m_dwListCount--;
  143. //Delete the IO Context
  144. delete(pIoContext->m_pPop3Context);
  145. delete(pIoContext);
  146. }
  147. m_pCursor=&m_ListHead;
  148. LeaveCriticalSection(&m_csListGuard);
  149. }