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

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
init.c
Abstract:
Initialization and shutdown routines for the GUM component
of the NT Cluster Service
Author:
John Vert (jvert) 17-Apr-1996
Revision History:
--*/
#include "gump.h"
//SS: Adding badly needed comments to this code
//
//Lock descriptions:
// GumpLock - protects GumTable, GumNodeGeneration, GumpLockerNode, GumReplay, GumUpdatePending
// GumpUpdateLock - protects GumpLockingNode, GumpLockQueue
// GumpSendUpdateLock - makes sure only one update is dispatched at a time
// and protect GumpLastXXX variables
//
//Lock Hierarchy
// GumpSendUpdateLock - look at s_GumJoinUpdateNode, send lock is acquired first then the gumlock.
// GumpLock - in gumpSyncEventHandler, GumpLock is held first before the gumupdate lock
// GumpUpdateLock - In s_GumAttemptJoinUpdate(), the send lock is acquired first and than the
// update lock
//
//
//Lock Usage
// GumpSyncEventHandler - acquires GumpLock and GumpUpdateLock. Dont want the gumpsynceventhandler
// to wait on gym
// GumSendUpdate - acquires GumSendUpdateLock while dispatching the update to the other nodes.
//
// Global information (used to be per-update)
//
DWORD GumpSequence;
CRITICAL_SECTION GumpUpdateLock;
CRITICAL_SECTION GumpSendUpdateLock;
CRITICAL_SECTION GumpRpcLock;
PVOID GumpLastBuffer;
DWORD GumpLastContext;
DWORD GumpLastBufferLength;
DWORD GumpLastUpdateType;
LIST_ENTRY GumpLockQueue;
DWORD GumpLockingNode;
DWORD GumpLockerNode;
BOOL GumpLastBufferValid;
//
// Table of per-update information
//
GUM_INFO GumTable[GumUpdateMaximum];
CRITICAL_SECTION GumpLock;
//
// Per-node information
//
GUM_NODE_WAIT GumNodeWait[ClusterMinNodeId + ClusterDefaultMaxNodes];
RPC_BINDING_HANDLE GumpRpcBindings[ClusterMinNodeId + ClusterDefaultMaxNodes];
RPC_BINDING_HANDLE GumpReplayRpcBindings[
ClusterMinNodeId + ClusterDefaultMaxNodes
];
DWORD GumNodeGeneration[ClusterMinNodeId + ClusterDefaultMaxNodes] = {0};
DWORD
GumInitialize(
VOID
)
/*++
Routine Description:
Initializes the Global Update Manager.
Arguments:
None.
Return Value:
ERROR_SUCCESS if successful
Win32 error code otherwise
--*/
{
DWORD i;
DWORD Status;
//
// Initialize global data
//
InitializeCriticalSection(&GumpLock);
InitializeCriticalSection(&GumpUpdateLock);
InitializeCriticalSection(&GumpSendUpdateLock);
InitializeCriticalSection(&GumpRpcLock);
GumpSequence = 0;
InitializeListHead(&GumpLockQueue);
GumpLockingNode = (DWORD)-1;
GumpLastBuffer = NULL;
GumpLastBufferValid = FALSE;
GumpLastContext = 0;
GumpLastBufferLength = 0;
//set it to illegal value;
GumpLastUpdateType = GumUpdateMaximum;
//
// Assume we are the locker node.
//
GumpLockerNode = NmGetNodeId(NmLocalNode);
//
// Initialize GumTable
//
for (i=0; i < GumUpdateMaximum; i++) {
GumTable[i].Receivers = NULL;
GumTable[i].Joined = FALSE;
ZeroMemory(&GumTable[i].ActiveNode,
sizeof(GumTable[i].ActiveNode));
GumTable[i].ActiveNode[NmGetNodeId(NmLocalNode)] = TRUE;
}
//
// Initialize per-node information
//
for (i=ClusterMinNodeId; i <= NmMaxNodeId; i++) {
GumpRpcBindings[i] = NULL;
GumpReplayRpcBindings[i] = NULL;
GumNodeWait[i].WaiterCount = 0;
GumNodeWait[i].hSemaphore = CreateSemaphore(NULL,0,100,NULL);
if (GumNodeWait[i].hSemaphore == NULL) {
CL_UNEXPECTED_ERROR( GetLastError() );
}
}
Status = EpRegisterEventHandler(CLUSTER_EVENT_NODE_DOWN_EX,
GumpEventHandler);
if (Status == ERROR_SUCCESS) {
Status = EpRegisterSyncEventHandler(CLUSTER_EVENT_NODE_DOWN_EX,
GumpSyncEventHandler);
}
return(Status);
}
VOID
GumShutdown(
VOID
)
/*++
Routine Description:
Shuts down the Global Update Manager.
Arguments:
None.
Return Value:
None.
--*/
{
DWORD i;
PGUM_RECEIVER Receiver;
PGUM_RECEIVER Next;
//
// Tear down GumTable
//
for (i=0; i < GumUpdateMaximum; i++) {
Receiver = GumTable[i].Receivers;
while (Receiver != NULL) {
Next = Receiver->Next;
LocalFree(Receiver);
Receiver = Next;
}
}
//
// Free per-node information
//
for (i=ClusterMinNodeId; i <= NmMaxNodeId; i++) {
if (GumpRpcBindings[i] != NULL) {
ClMsgDeleteRpcBinding(GumpRpcBindings[i]);
}
if (GumpReplayRpcBindings[i] != NULL) {
ClMsgDeleteRpcBinding(GumpReplayRpcBindings[i]);
}
if (GumNodeWait[i].hSemaphore != NULL) {
CloseHandle(GumNodeWait[i].hSemaphore);
}
}
DeleteCriticalSection(&GumpLock);
DeleteCriticalSection(&GumpUpdateLock);
DeleteCriticalSection(&GumpSendUpdateLock);
}