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.
|
|
/*++
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); }
|