⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scorder.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++


Module Name:

    scorder.cxx

Abstract:

    Small client -- implementation of message ordering class


--*/
#include <sc.hxx>
#include <scorder.hxx>
#include <svsutil.hxx>
#include <scqueue.hxx>
#include <scqman.hxx>
#include <scsman.hxx>
#include <sccomp.hxx>

unsigned int ScSequenceCollection::Hash (GUID *pguid, GUID *pOtherGuid) {
	unsigned int uiRes = 0;

	unsigned int *p1 = (unsigned int *)pguid;
	unsigned int *p2 = (unsigned int *)&pOtherGuid;

	for (int i = 0 ; i < 4 ; ++i, ++p1, ++p2)
		uiRes += (*p1) ^ (*p2);

	return uiRes % SCSEQUENCE_HASH_BUCKETS;
}

unsigned int ScSequenceCollection::Hash (WCHAR *sz) {
	int uiRes = 0;

	for ( ; ; ) {
		if (sz[0] == '\0')
			break;

		if (sz[1] == '\0') {
			uiRes += towupper (sz[0]);
			break;
		}

		uiRes += towupper (sz[0]) ^ towupper (sz[1]);
		sz += 2;
	}

	return uiRes % SCSEQUENCE_HASH_BUCKETS;
}

unsigned int ScSequenceCollection::Hash (GUID *pGuid) {
	unsigned int uiRes = 0;

	unsigned int *p1 = (unsigned int *)pGuid;

	uiRes += p1[0] ^ p1[3] + p1[1] ^ p1[2];

	return uiRes % SCSEQUENCE_HASH_BUCKETS;
}

ScOrderSeq *ScSequenceCollection::HashOrderSequence (ScQueue *pQueue, GUID *pguidStreamId, GUID *pguidQueueName, GUID *pguidOrderAckName, unsigned int uiSequenceFlags) {
//	SVSUTIL_ASSERT (pQueue->qp.bIsIncoming);
//	SVSUTIL_ASSERT (pQueue->qp.bTransactional);

	int iPos = Hash (pguidStreamId, pguidQueueName);
	ScOrderSeq *pSeq = pSeqBuckets[iPos];
	while (pSeq) {
		//
		//	Same server can be known by different names, only guid equivalence is to be tested...
		//
		if (((! pQueue) || (pSeq->p->guidQ == pQueue->qp.guid)) && (pSeq->p->guidStreamId == *pguidStreamId) && (pSeq->p->guidQueueName == *pguidQueueName)) {
			return pSeq;
		}
		pSeq = pSeq->pNextHash;
	}

	if (! pguidOrderAckName)
		return NULL;

	pSeq = (ScOrderSeq *)svsutil_GetFixed (pfmOrderSeq);

	if (! pSeq)
		return NULL;

	pSeq->p = PersistBlock();
	if (! pSeq->p) {
		svsutil_FreeFixed (pSeq, pfmOrderSeq);
		return NULL;
	}

	pSeq->pQueue    = pQueue;
	pSeq->fActive   = FALSE;
	pSeq->ipAddr.S_un.S_addr = INADDR_NONE;

	pSeq->pPrevActive = NULL;
	pSeq->pNextActive = NULL;

	pSeq->pNextHash = pSeqBuckets[iPos];
	pSeqBuckets[iPos] = pSeq;

	pSeq->p->guidQ          = pQueue->qp.guid;
	pSeq->p->guidQueueName  = *pguidQueueName;
	pSeq->p->guidStreamId   = *pguidStreamId;
	pSeq->p->guidOrderAck   = *pguidOrderAckName;
	pSeq->p->llCurrentSeqID = 0;
	pSeq->p->uiCurrentSeqN  = 0;
	pSeq->p->uiLastAccessS  = 0;
	pSeq->p->uiBlockFlags   = uiSequenceFlags;

	return pSeq;
}

int ScSequenceCollection::SaveSequence (ScOrderSeq *pSeq) {
	SVSUTIL_ASSERT (pSeq->pQueue);
	SVSUTIL_ASSERT (pSeq->p);

	int iCluster = FindCluster (pSeq->p);
	if (iCluster < 0)
		return FALSE;

	pSeq->p->uiLastAccessS = scutil_now ();

	if ((! pSeq->fActive) && pSeq->p->llCurrentSeqID) {
		SVSUTIL_ASSERT (pSeq->p->uiCurrentSeqN);
		SVSUTIL_ASSERT(! pSeq->pPrevActive);
		SVSUTIL_ASSERT(! pSeq->pNextActive);

		pSeq->fActive     = TRUE;
		pSeq->pNextActive = pSeqActive;
		pSeqActive        = pSeq;

		if (pSeq->pNextActive)
			pSeq->pNextActive->pPrevActive = pSeq;
		else								// Only start pulsing on the first active event...
			svsutil_SetAttrTimer (gMem->pTimer, (SVSHandle)hSequencePulse, SCSEQUENCE_R_ACKSEND * gMachine->uiOrderAckScale * 1000);
	}

	ppClusters[iCluster]->iDirty = TRUE;

	return FlushBackup ();
}

void ScSequenceCollection::DeleteQueue (ScQueue *pQueue) {
	SVSUTIL_ASSERT (gMem->IsLocked());

	if (! (pQueue->qp.bIsIncoming && pQueue->qp.bTransactional))
		return;

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_ORDER, L"Deleting sequences associated with %s...\n", pQueue->lpszFormatName);
#endif

	for (int i = 0 ; i < SCSEQUENCE_HASH_BUCKETS ; ++i) {
		ScOrderSeq *pSeq = pSeqBuckets[i];
		ScOrderSeq *pParentSeq = NULL;

		while (pSeq) {
			SVSUTIL_ASSERT (pSeq->p->uiLastAccessS);

			if (pSeq->pQueue == pQueue) {
				SVSUTIL_ASSERT (pSeq->p->guidQ == pQueue->qp.guid);

				if (pSeq->fActive) {
					if (pSeq == pSeqActive) {
						pSeqActive = pSeq->pNextActive;
						if (pSeqActive)
							pSeqActive->pPrevActive = NULL;
					} else {
						SVSUTIL_ASSERT (pSeq->pPrevActive);
						pSeq->pPrevActive->pNextActive = pSeq->pNextActive;
						if (pSeq->pNextActive)
							pSeq->pNextActive->pPrevActive = pSeq->pPrevActive;
					}
				} else
					SVSUTIL_ASSERT ((! pSeq->pPrevActive) && (! pSeq->pNextActive));

				if (! pParentSeq)
					pSeqBuckets[i] = pSeq->pNextHash;
				else
					pParentSeq->pNextHash = pSeq->pNextHash;

				int iCluster = FindCluster (pSeq->p);

				SVSUTIL_ASSERT ((iCluster >= 0) && (iCluster < (int)uiClustersCount));
				SVSUTIL_ASSERT ((ppClusters[iCluster]->h.uiFirstFreeBlock < SCSEQUENCE_ENTRIES_PER_BLOCK) || (ppClusters[iCluster]->h.uiFirstFreeBlock == -1));

				ppClusters[iCluster]->iNumFree++;
				ppClusters[iCluster]->iDirty = TRUE;

				pSeq->p->uiLastAccessS = 0;
				pSeq->p->uiCurrentSeqN = ppClusters[iCluster]->h.uiFirstFreeBlock;
				ppClusters[iCluster]->h.uiFirstFreeBlock = pSeq->p - ppClusters[iCluster]->pos;

				SVSUTIL_ASSERT (ppClusters[iCluster]->h.uiFirstFreeBlock < SCSEQUENCE_ENTRIES_PER_BLOCK);

				ScOrderSeq *pSeqNext = pSeq->pNextHash;
				svsutil_FreeFixed (pSeq, pfmOrderSeq);
				pSeq = pSeqNext;
				continue;
			}

			pParentSeq = pSeq;
			pSeq = pSeq->pNextHash;
		}
	}

	FlushBackup ();
}

int ScSequenceCollection::CloseBackup (void) {
	if (hBackupFile != INVALID_HANDLE_VALUE)
		CloseHandle (hBackupFile);

	hBackupFile = INVALID_HANDLE_VALUE;

	return TRUE;
}

int ScSequenceCollection::CloseStrings (void) {
	if (hStringFile != INVALID_HANDLE_VALUE)
		CloseHandle (hStringFile);

	hStringFile = INVALID_HANDLE_VALUE;

	return TRUE;
}

int ScSequenceCollection::OpenBackup (void) {
	if (hBackupFile != INVALID_HANDLE_VALUE)
		return TRUE;

	hBackupFile = CreateFile (lpszBackupName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);

	if (hBackupFile != INVALID_HANDLE_VALUE)
		return TRUE;

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_ORDER, L"Failed to open file %s\n", lpszBackupName);
#endif

	return FALSE;
}

int ScSequenceCollection::OpenStrings (void) {
	if (hStringFile != INVALID_HANDLE_VALUE)
		return TRUE;

	hStringFile = CreateFile (lpszStringName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);

	if (hStringFile != INVALID_HANDLE_VALUE) {
		if (SetFilePointer (hStringFile, 0, NULL, FILE_END) == 0xffffffff) {
			CloseStrings ();
			return FALSE;
		}

		return TRUE;
	}

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_ORDER, L"Failed to open file %s\n", lpszStringName);
#endif

	return FALSE;
}

int ScSequenceCollection::FlushBackup (void) {
	for (int i = 0 ; i < (int)uiClustersCount ; ++i) {
		if (ppClusters[i]->iDirty) {
			if (! OpenBackup ())
				return FALSE;

			if (SetFilePointer (hBackupFile, i * SC_FS_UNIT, 0, FILE_BEGIN) == 0xffffffff) {
#if defined (SC_VERBOSE)
				scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't seek to %d in %s\n", i * SC_FS_UNIT, lpszBackupName);
#endif
				return FALSE;
			}

			DWORD dwBytes = 0;

			if ((! WriteFile (hBackupFile, ppClusters[i]->ac, sizeof(ppClusters[i]->ac), &dwBytes, NULL)) ||
				(dwBytes != sizeof(ppClusters[i]->ac))) {
#if defined (SC_VERBOSE)
				scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't write %d bytes to %s\n", sizeof(ppClusters[i]->ac), lpszBackupName);
#endif
				return FALSE;
			}

			ppClusters[i]->iDirty = FALSE;
		}
	}

	if (hBackupFile != INVALID_HANDLE_VALUE) {
		if (SetFilePointer (hBackupFile, i * SC_FS_UNIT, 0, FILE_BEGIN) == 0xffffffff) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't seek to %d in %s\n", i * SC_FS_UNIT, lpszBackupName);
#endif
			return FALSE;
		}

		SetEndOfFile (hBackupFile);
		FlushFileBuffers (hBackupFile);

		uiLastBackupAccessT = GetTickCount ();
	}

	return TRUE;
}

int ScSequenceCollection::AddNewCluster (void) {
	if (uiClustersCount == uiClustersAlloc) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_ORDER, L"Adding new sequence cluster...\n");
#endif

		unsigned int l_uiClustersAlloc = uiClustersAlloc + SCSEQUENCE_CLUSTERALLOC;
		ScOrderCluster **l_ppClusters = (ScOrderCluster **)g_funcAlloc (sizeof(ScOrderCluster *) * l_uiClustersAlloc, g_pvAllocData);
		if (! l_ppClusters) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_ORDER, L"Failed to expand cluster array - no memory...\n");
#endif
			return FALSE;
		}

		if (ppClusters) {
			memcpy (l_ppClusters, ppClusters, sizeof(ScOrderCluster *) * uiClustersAlloc);
			g_funcFree (ppClusters, g_pvFreeData);
		}

		ppClusters = l_ppClusters;
		uiClustersAlloc = l_uiClustersAlloc;
	}

	ScOrderCluster *pCluster = (ppClusters[uiClustersCount] = (ScOrderCluster *)g_funcAlloc (sizeof(ScOrderCluster), g_pvAllocData));

	if (! pCluster) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_ORDER, L"Failed to alloc new sequence cluster...\n");
#endif
		return FALSE;
	}

	++uiClustersCount;

	memset (&pCluster->ac, 0, sizeof(pCluster->ac));

	pCluster->iNumFree    = SCSEQUENCE_ENTRIES_PER_BLOCK;
	pCluster->iDirty      = TRUE;
	pCluster->h.uiFirstFreeBlock = 0;
	pCluster->h.uiMagic1  = SCSEQUENCE_MAGIC1;
	pCluster->h.uiMagic2  = SCSEQUENCE_MAGIC2;
	pCluster->h.uiVersion = SCSEQUENCE_VERSION;

	for (int i = 0 ; i < SCSEQUENCE_ENTRIES_PER_BLOCK - 1; ++i)
		pCluster->pos[i].uiCurrentSeqN = i + 1;

	pCluster->pos[i].uiCurrentSeqN = (DWORD)-1;

	return TRUE;
}

ScPersistOrderSeq *ScSequenceCollection::PersistBlock (void) {
	for (int i = 0 ; i < (int)uiClustersCount ; ++i) {
		if (ppClusters[i]->h.uiFirstFreeBlock != -1) {
			SVSUTIL_ASSERT (ppClusters[i]->h.uiFirstFreeBlock < SCSEQUENCE_ENTRIES_PER_BLOCK);

			ScPersistOrderSeq *p = &ppClusters[i]->pos[ppClusters[i]->h.uiFirstFreeBlock];

			SVSUTIL_ASSERT (p->uiLastAccessS == 0);
			SVSUTIL_ASSERT (p->uiCurrentSeqN < SCSEQUENCE_ENTRIES_PER_BLOCK);

			ppClusters[i]->iDirty = TRUE;
			ppClusters[i]->h.uiFirstFreeBlock = p->uiCurrentSeqN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -