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.

222 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Initialization and shutdown routines for the GUM component
  7. of the NT Cluster Service
  8. Author:
  9. John Vert (jvert) 17-Apr-1996
  10. Revision History:
  11. --*/
  12. #include "gump.h"
  13. //SS: Adding badly needed comments to this code
  14. //
  15. //Lock descriptions:
  16. // GumpLock - protects GumTable, GumNodeGeneration, GumpLockerNode, GumReplay, GumUpdatePending
  17. // GumpUpdateLock - protects GumpLockingNode, GumpLockQueue
  18. // GumpSendUpdateLock - makes sure only one update is dispatched at a time
  19. // and protect GumpLastXXX variables
  20. //
  21. //Lock Hierarchy
  22. // GumpSendUpdateLock - look at s_GumJoinUpdateNode, send lock is acquired first then the gumlock.
  23. // GumpLock - in gumpSyncEventHandler, GumpLock is held first before the gumupdate lock
  24. // GumpUpdateLock - In s_GumAttemptJoinUpdate(), the send lock is acquired first and than the
  25. // update lock
  26. //
  27. //
  28. //Lock Usage
  29. // GumpSyncEventHandler - acquires GumpLock and GumpUpdateLock. Dont want the gumpsynceventhandler
  30. // to wait on gym
  31. // GumSendUpdate - acquires GumSendUpdateLock while dispatching the update to the other nodes.
  32. //
  33. // Global information (used to be per-update)
  34. //
  35. DWORD GumpSequence;
  36. CRITICAL_SECTION GumpUpdateLock;
  37. CRITICAL_SECTION GumpSendUpdateLock;
  38. CRITICAL_SECTION GumpRpcLock;
  39. PVOID GumpLastBuffer;
  40. DWORD GumpLastContext;
  41. DWORD GumpLastBufferLength;
  42. DWORD GumpLastUpdateType;
  43. LIST_ENTRY GumpLockQueue;
  44. DWORD GumpLockingNode;
  45. DWORD GumpLockerNode;
  46. BOOL GumpLastBufferValid;
  47. //
  48. // Table of per-update information
  49. //
  50. GUM_INFO GumTable[GumUpdateMaximum];
  51. CRITICAL_SECTION GumpLock;
  52. //
  53. // Per-node information
  54. //
  55. GUM_NODE_WAIT GumNodeWait[ClusterMinNodeId + ClusterDefaultMaxNodes];
  56. RPC_BINDING_HANDLE GumpRpcBindings[ClusterMinNodeId + ClusterDefaultMaxNodes];
  57. RPC_BINDING_HANDLE GumpReplayRpcBindings[
  58. ClusterMinNodeId + ClusterDefaultMaxNodes
  59. ];
  60. DWORD GumNodeGeneration[ClusterMinNodeId + ClusterDefaultMaxNodes] = {0};
  61. DWORD
  62. GumInitialize(
  63. VOID
  64. )
  65. /*++
  66. Routine Description:
  67. Initializes the Global Update Manager.
  68. Arguments:
  69. None.
  70. Return Value:
  71. ERROR_SUCCESS if successful
  72. Win32 error code otherwise
  73. --*/
  74. {
  75. DWORD i;
  76. DWORD Status;
  77. //
  78. // Initialize global data
  79. //
  80. InitializeCriticalSection(&GumpLock);
  81. InitializeCriticalSection(&GumpUpdateLock);
  82. InitializeCriticalSection(&GumpSendUpdateLock);
  83. InitializeCriticalSection(&GumpRpcLock);
  84. GumpSequence = 0;
  85. InitializeListHead(&GumpLockQueue);
  86. GumpLockingNode = (DWORD)-1;
  87. GumpLastBuffer = NULL;
  88. GumpLastBufferValid = FALSE;
  89. GumpLastContext = 0;
  90. GumpLastBufferLength = 0;
  91. //set it to illegal value;
  92. GumpLastUpdateType = GumUpdateMaximum;
  93. //
  94. // Assume we are the locker node.
  95. //
  96. GumpLockerNode = NmGetNodeId(NmLocalNode);
  97. //
  98. // Initialize GumTable
  99. //
  100. for (i=0; i < GumUpdateMaximum; i++) {
  101. GumTable[i].Receivers = NULL;
  102. GumTable[i].Joined = FALSE;
  103. ZeroMemory(&GumTable[i].ActiveNode,
  104. sizeof(GumTable[i].ActiveNode));
  105. GumTable[i].ActiveNode[NmGetNodeId(NmLocalNode)] = TRUE;
  106. }
  107. //
  108. // Initialize per-node information
  109. //
  110. for (i=ClusterMinNodeId; i <= NmMaxNodeId; i++) {
  111. GumpRpcBindings[i] = NULL;
  112. GumpReplayRpcBindings[i] = NULL;
  113. GumNodeWait[i].WaiterCount = 0;
  114. GumNodeWait[i].hSemaphore = CreateSemaphore(NULL,0,100,NULL);
  115. if (GumNodeWait[i].hSemaphore == NULL) {
  116. CL_UNEXPECTED_ERROR( GetLastError() );
  117. }
  118. }
  119. Status = EpRegisterEventHandler(CLUSTER_EVENT_NODE_DOWN_EX,
  120. GumpEventHandler);
  121. if (Status == ERROR_SUCCESS) {
  122. Status = EpRegisterSyncEventHandler(CLUSTER_EVENT_NODE_DOWN_EX,
  123. GumpSyncEventHandler);
  124. }
  125. return(Status);
  126. }
  127. VOID
  128. GumShutdown(
  129. VOID
  130. )
  131. /*++
  132. Routine Description:
  133. Shuts down the Global Update Manager.
  134. Arguments:
  135. None.
  136. Return Value:
  137. None.
  138. --*/
  139. {
  140. DWORD i;
  141. PGUM_RECEIVER Receiver;
  142. PGUM_RECEIVER Next;
  143. //
  144. // Tear down GumTable
  145. //
  146. for (i=0; i < GumUpdateMaximum; i++) {
  147. Receiver = GumTable[i].Receivers;
  148. while (Receiver != NULL) {
  149. Next = Receiver->Next;
  150. LocalFree(Receiver);
  151. Receiver = Next;
  152. }
  153. }
  154. //
  155. // Free per-node information
  156. //
  157. for (i=ClusterMinNodeId; i <= NmMaxNodeId; i++) {
  158. if (GumpRpcBindings[i] != NULL) {
  159. ClMsgDeleteRpcBinding(GumpRpcBindings[i]);
  160. }
  161. if (GumpReplayRpcBindings[i] != NULL) {
  162. ClMsgDeleteRpcBinding(GumpReplayRpcBindings[i]);
  163. }
  164. if (GumNodeWait[i].hSemaphore != NULL) {
  165. CloseHandle(GumNodeWait[i].hSemaphore);
  166. }
  167. }
  168. DeleteCriticalSection(&GumpLock);
  169. DeleteCriticalSection(&GumpUpdateLock);
  170. DeleteCriticalSection(&GumpSendUpdateLock);
  171. }
  172.