Source code of Windows XP (NT5)
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.

259 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name :
  4. queue.cxx
  5. Abstract:
  6. Implements a queue
  7. Author:
  8. Rohan Phillips ( Rohanp ) 11-Dec-1995
  9. Project:
  10. SMTP Server DLL
  11. Functions Exported:
  12. Revision History:
  13. --*/
  14. /************************************************************
  15. * Include Headers
  16. ************************************************************/
  17. #define INCL_INETSRV_INCS
  18. #include "smtpinc.h"
  19. #include "remoteq.hxx"
  20. #include "timemath.h"
  21. /*++
  22. Name :
  23. PERSIST_QUEUE::InitializeQueue
  24. Description:
  25. This function initializes all the class
  26. member functions.
  27. Arguments:
  28. pszQueueName - Name of the on disk queue
  29. Flags - Queue flags
  30. Retry - How long we should retry failed deliveries
  31. FlushQ - How often we should flush the queue to disk
  32. Returns:
  33. TRUE if all memory allocations and all I/O operations pass
  34. FALSE otherwise
  35. --*/
  36. BOOL PERSIST_QUEUE::InitializeQueue (void)
  37. {
  38. TraceFunctEnterEx((LPARAM)this, "PERSIST_QUEUE::InitializeQueue");
  39. // Now, initialize the queue structure:
  40. m_QData.Entries = 0;
  41. m_QData.RetryInterval = 0;
  42. m_QData.StoreInterval = 0;
  43. m_QData.Flags = 0;
  44. m_QData.LastStore = (LONGLONG) 0;
  45. //create the thread that processes things out of the
  46. //the queue
  47. DWORD ThreadId;
  48. DWORD Loop = 0;
  49. for (Loop = 0; Loop < m_NumThreads; Loop++)
  50. {
  51. m_ThreadHandle[Loop] = CreateThread (NULL, 0, PERSIST_QUEUE::QueueThreadRoutine, this, 0, &ThreadId);
  52. if (m_ThreadHandle[Loop] == NULL)
  53. {
  54. TraceFunctLeaveEx((LPARAM)this);
  55. return FALSE;
  56. }
  57. }
  58. TraceFunctLeaveEx((LPARAM)this);
  59. return TRUE;
  60. }
  61. /*++
  62. Name :
  63. PERSIST_QUEUE::CreateQueue
  64. Description:
  65. This is the static member function that creates the Queue
  66. Arguments:
  67. Qtype - the type of queue to create (i.e Local, Remote, etc.)
  68. Returns:
  69. TRUE if all memory allocations and all I/O operaations pass
  70. FALSE otherwise
  71. --*/
  72. PERSIST_QUEUE * PERSIST_QUEUE::CreateQueue(QUEUE_TYPE Qtype, SMTP_SERVER_INSTANCE * pSmtpInst)
  73. {
  74. PERSIST_QUEUE * pQueue = NULL;
  75. _ASSERT (pSmtpInst != NULL);
  76. if(Qtype == REMOTEQ)
  77. {
  78. pQueue = new REMOTE_QUEUE(pSmtpInst);
  79. if(pQueue)
  80. {
  81. pQueue->SetNumThreads(pSmtpInst->GetMaxRemoteQThreads());
  82. }
  83. else
  84. {
  85. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  86. return(NULL);
  87. }
  88. }
  89. else
  90. {
  91. _ASSERT(FALSE);
  92. return NULL;
  93. }
  94. //initialize the queue
  95. if(!pQueue->InitializeQueue())
  96. {
  97. delete pQueue;
  98. pQueue = NULL;
  99. }
  100. return pQueue;
  101. }
  102. /*++
  103. Name :
  104. PERSIST_QUEUE::ProcessQueueEvents
  105. Description:
  106. This is the virtual process function
  107. that all derived classes must override
  108. This function is different depending on
  109. what it is suppose to do. Take a look
  110. at localq.cxx and remoteq.cxx for examples.
  111. Arguments:
  112. Returns:
  113. Always TRUE
  114. --*/
  115. BOOL PERSIST_QUEUE::ProcessQueueEvents(ISMTPConnection *pISMTPConnection)
  116. {
  117. return TRUE;
  118. }
  119. /*++
  120. Name :
  121. PERSIST_QUEUE::FlushQueueEvents
  122. Description:
  123. This function deletes all entries from the queue
  124. Arguments:
  125. Returns:
  126. --*/
  127. void PERSIST_QUEUE::FlushQueueEvents(void)
  128. {
  129. PLIST_ENTRY pEntry;
  130. PQUEUE_ENTRY pQEntry;
  131. TraceFunctEnterEx((LPARAM)this, "PERSIST_QUEUE::FlushQueueEvents");
  132. _ASSERT (GetParentInst() != NULL);
  133. LockQ();
  134. //delete all entries from the list
  135. while(!IsListEmpty (&m_QHead))
  136. {
  137. GetParentInst()->StopHint();
  138. pEntry = RemoveHeadList (&m_QHead);
  139. pQEntry = CONTAINING_RECORD( pEntry, PERSIST_QUEUE_ENTRY, m_QEntry);
  140. pQEntry->BeforeDelete();
  141. delete pQEntry;
  142. }
  143. //reset the stop hint
  144. GetParentInst()->SetStopHint(2);
  145. UnLockQ();
  146. TraceFunctLeaveEx((LPARAM)this);
  147. }
  148. /*++
  149. Name :
  150. PERSIST_QUEUE::QueueThreadRoutine
  151. Description:
  152. This function is the static member
  153. function that gets passed to CreateThread
  154. to initialize the queue.
  155. Arguments:
  156. A pointer to a PERSIST_QUEUE
  157. Returns:
  158. --*/
  159. DWORD WINAPI PERSIST_QUEUE::QueueThreadRoutine(void * ThisPtr)
  160. {
  161. PQUEUE QueuePtr = (PQUEUE) ThisPtr;
  162. HRESULT hr = S_OK;
  163. ISMTPConnection *pISMTPConnection = NULL;
  164. TraceFunctEnterEx((LPARAM)QueuePtr, "PERSIST_QUEUE::QueueThreadRoutine");
  165. while(TRUE)
  166. {
  167. pISMTPConnection = NULL;
  168. hr = QueuePtr->GetParentInst()->GetConnManPtr()->GetNextConnection(&pISMTPConnection);
  169. if(!FAILED(hr))
  170. {
  171. //call the virtual process function
  172. QueuePtr->ProcessQueueEvents(pISMTPConnection);
  173. //if we are shutting down, break out of the loop
  174. if (QueuePtr->GetParentInst()->IsShuttingDown())
  175. goto Out;
  176. }
  177. else
  178. {
  179. //if we are shutting down, break out of the loop
  180. if (QueuePtr->GetParentInst()->IsShuttingDown())
  181. goto Out;
  182. }
  183. }
  184. Out:
  185. TraceFunctLeaveEx((LPARAM)QueuePtr);
  186. return 1;
  187. }