Boolean VNonVirtualCriticalSection::Lock()
{

	VTaskID currentTaskID = VTask::GetCurrentID();
	do {

		VTaskID owner = (VTaskID) VInterlocked::CompareExchange((sLONG*) &fOwner, (sLONG) NULL_TASK_ID, (sLONG) currentTaskID);
		if (owner == NULL_TASK_ID)
		{
			assert(fUseCount == 0);
			fUseCount = 1;
		}
		else if (fOwner == currentTaskID)
		{
			++fUseCount;
		}
		else
		{
			sLONG	unlockCount = sUnlockCount;

			VSyncEvent*	event = VInterlocked::ExchangePtr( &fEvent);
			if (event != NULL)
			{
				event->Retain();
				if (VInterlocked::CompareExchangePtr((void **)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					event->Release();
					VTask::YieldNow();
				}
				else
				{
					while (VInterlocked::CompareExchange(&sUnlockCount, sUnlockCount, sUnlockCount) != sUnlockCount)
						VTask::YieldNow();

					if (sUnlockCount == unlockCount)
						event->Lock( 100);
					else
						VTask::YieldNow();
				}
				event->Release();
			}
			else
			{
				event = new VSyncEvent;

				if (VInterlocked::CompareExchangePtr((void **)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					event->Release();
					VTask::YieldNow();
				}
			}
		}

	} while(fOwner != currentTaskID);
	
	return true;
}
Boolean VSmallCriticalSection::Lock()
{
	sWORD	currentTaskID = (sWORD)VTask::GetCurrentID();
	LongAsDoubleWord	doubleWord;

	doubleWord.first = (sWORD)currentTaskID;
	doubleWord.second = 0;

	do {

		sLONG owner = VInterlocked::CompareExchange((sLONG*) &fOwner, (sLONG) 0, *((sLONG*) &doubleWord));
		if (owner == 0)
		{
			assert(fUseCount == 0);
			fUseCount = 1;
		}
		else if (fOwner == currentTaskID)
		{
			++fUseCount;
		}
		else
		{
			sLONG	unlockCount = sUnlockCount;
			VSyncEvent* event = VInterlocked::ExchangePtr(&fEvent);
			if (event != NULL)
			{
				event->Retain();

				if (VInterlocked::CompareExchangePtr((void**)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					VTask::YieldNow();
				}
				else
				{
					if (sUnlockCount == unlockCount)
						event->Lock(100);
					else
						VTask::YieldNow();
				}
				
				event->Release();
			}
			else
			{
				event = new VSyncEvent;

				if (VInterlocked::CompareExchangePtr((void**)&fEvent, NULL, event) != NULL)
				{
					event->Release();
					VTask::YieldNow();
				}
			}
		}
	} while (fOwner != currentTaskID);
	
	return true;
}
Boolean VSmallCriticalSection::Unlock()
{
	//assert((fOwner == (sWORD)VTask::GetCurrentID()) && (fUseCount > 0) && (fUseCount < 32000L));

	assert(fUseCount > 0);
	VSyncEvent*	event = NULL;

	VInterlocked::Increment(&sUnlockCount);

	// Unlock or another successfull lock can only be called from same thead (so no contention can occur on fUseCount)
	if (--fUseCount == 0)
	{
		// capture currently set event
		event = VInterlocked::ExchangePtr(&fEvent);
		VTaskID owner = VInterlocked::Exchange((sLONG*) &fOwner, (sLONG) 0);
		//assert(owner == VTask::GetCurrentID());

		if (event != NULL)
		{
			event->Unlock();
			event->Release();
		}
	}
	return true;
}
Boolean VDBFlushMgr::NeedsBytes( VSize inNeededBytes)
{
	Boolean isOK = false;
	if (VTask::GetCurrent() != fFlushTask)
	{
		sLONG	lastStamp = StartFlushStamp;
		VTaskLock lock(&StartFlushMutex);
		if (lastStamp == StartFlushStamp)
		{
			{
				VSyncEvent* wait = NewFlushEnoughMemEvent(inNeededBytes);

				Flush( false);


				fNbWaitingClients++;
				wait->Lock();
				fNbWaitingClients--;
				isOK = true;
				StartFlushStamp++;
				wait->Release();
			}
		}
		else
			isOK = true; // si le stamp a change, cela veut dire qu'une autre tache a deja demande au flush de liberer sur disk de l'espace
	}
	return isOK;
}
VError VJSContextPool::Clear()
{
	VError err = VE_OK;

	bool savedEnabledState = fEnabled;	// save the enabled state

	fEnabled = false;

	VSyncEvent *syncEvent = WaitForNumberOfUsedContextEqualZero();
	if (syncEvent != NULL)
	{
		syncEvent->Lock();
		syncEvent->Release();
	}

	if (fPoolMutex.Lock())
	{
		for (MapOfJSContext_iter iter = fUnusedContexts.begin() ; iter != fUnusedContexts.end() ; ++iter)
		{
			xbox_assert(iter->second->IsReusable());

			VJSGlobalObject *globalObject = iter->second->GetGlobalObject();
			if (globalObject != NULL)
				globalObject->GarbageCollect();

			_ReleaseContext( iter->first);

			delete iter->second;
			--fReusableContextCount;
		}
		
		xbox_assert(fReusableContextCount == 0);
		fUnusedContexts.clear();

		fPoolMutex.Unlock();
	}

	fEnabled = savedEnabledState;	// restore the enabled state

	return err;
}
Boolean VNonVirtualCriticalSection::Unlock()
{
	assert((fOwner == VTask::GetCurrentID()) && (fUseCount > 0) && (fUseCount < 32000L));

	//assert(fUseCount > 0);
	VSyncEvent*	event = NULL;

	VInterlocked::Increment(&sUnlockCount);

	if (--fUseCount == 0)
	{
		event = VInterlocked::ExchangePtr(&fEvent);
		VTaskID	owner = VInterlocked::Exchange((sLONG*) &fOwner, (sLONG) NULL_TASK_ID);
		//assert(owner == VTask::GetCurrentID());

		if (event != NULL)
		{
			event->Unlock();
			event->Release();
		}
	}
	
	return true;
}
void VDBFlushMgr::Flush( Boolean inSynchronous, Boolean onlyForAllWritten)
{
#if debuglr == 101
	if (fFlushProgress != nil && !fFlushProgress->IsManagerValid())
	{
		sLONG xdebug = 1; // put a break here
	}
#endif

	if (fFlushTask != nil) 
	{
		if (inSynchronous)
		{	
#if trackClose
			trackDebugMsg("call flush synchronous\n");
#endif
			sLONG	lastStamp = StartFlushStamp;
			VSyncEvent* wait = nil;
			{
				{
					VTaskLock lock(&StartFlushMutex);
					if (lastStamp == StartFlushStamp)
					{
						if (onlyForAllWritten)
							wait = NewFlushAllWrittenEvent();
						else
							wait = NewFlushEndEvent();
#if trackClose
							trackDebugMsg("call flush synchronous after mutex\n");
#endif						
							Flush( false);
					}
				}

				if (wait != nil)
				{
					wait->Lock();
					wait->Release();
					{
						VTaskLock lock(&StartFlushMutex);
						StartFlushStamp++;
					}
				}
#if trackClose
				trackDebugMsg("end of call flush synchronous\n");
#endif			
			}
		}
		else // pas synchrone
		{
#if trackClose
			trackDebugMsg("call flush asynchronous\n");
#endif			
			if (StartFlushMutex.TryToLock())
			{
#if trackClose
				trackDebugMsg("call flush asynchronous after mutex\n");
#endif						
				{
					VTaskLock lock(&DirtyMutext);
					fIsAskingFlush = true;
					//fFlushTask->WakeUp();
				}
				WakeUp();
				StartFlushMutex.Unlock();
#if trackClose
				trackDebugMsg("release mutext for call flush asynchronous\n");
#endif						
			}
		}
	}
}