mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-29 12:18:01 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //
 | |
| // Mutex_WIN32.cpp
 | |
| //
 | |
| // $Id: //poco/1.4/Foundation/src/Mutex_WIN32.cpp#1 $
 | |
| //
 | |
| // Library: Foundation
 | |
| // Package: Threading
 | |
| // Module:  Mutex
 | |
| //
 | |
| // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
 | |
| // and Contributors.
 | |
| //
 | |
| // SPDX-License-Identifier:	BSL-1.0
 | |
| //
 | |
| 
 | |
| 
 | |
| #include "Poco/Mutex_WIN32.h"
 | |
| #include "Poco/Thread.h"
 | |
| #include "Poco/Timestamp.h"
 | |
| 
 | |
| 
 | |
| namespace Poco {
 | |
| 
 | |
| 
 | |
| MutexImpl::MutexImpl(MutexTypeImpl type)
 | |
| 	: _lockCount(0)
 | |
| 	, _recursive(type == MUTEX_RECURSIVE_IMPL)
 | |
| {
 | |
| 	// the fct has a boolean return value under WInnNt/2000/XP but not on Win98
 | |
| 	// the return only checks if the input address of &_cs was valid, so it is safe to omit it
 | |
| 	InitializeCriticalSectionAndSpinCount(&_cs, 4000);
 | |
| }
 | |
| 
 | |
| 
 | |
| MutexImpl::~MutexImpl()
 | |
| {
 | |
| 	DeleteCriticalSection(&_cs);
 | |
| }
 | |
| 
 | |
| 
 | |
| void MutexImpl::lockImpl()
 | |
| {
 | |
| 	try
 | |
| 	{
 | |
| 		EnterCriticalSection(&_cs);
 | |
| 		++_lockCount;
 | |
| 
 | |
| 		if (!_recursive && _lockCount > 1)
 | |
| 		{
 | |
| 			// We're trying to go recursive so self-deadlock
 | |
| 			Thread::current()->join();
 | |
| 		}
 | |
| 	}
 | |
| 	catch (...)
 | |
| 	{
 | |
| 		throw SystemException("cannot lock mutex");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| bool MutexImpl::tryLockImpl()
 | |
| {
 | |
| 	try
 | |
| 	{
 | |
| 		if (TryEnterCriticalSection(&_cs) == 0)
 | |
| 			return false;
 | |
| 
 | |
| 		if (!_recursive && _lockCount > 0)
 | |
| 		{
 | |
| 			LeaveCriticalSection(&_cs);
 | |
| 			return false;
 | |
| 		}
 | |
| 		
 | |
| 		++_lockCount;
 | |
| 		return true;
 | |
| 	}
 | |
| 	catch (...)
 | |
| 	{
 | |
| 	}
 | |
| 	throw SystemException("cannot lock mutex");
 | |
| }
 | |
| 
 | |
| 
 | |
| bool MutexImpl::tryLockImpl(long milliseconds)
 | |
| {
 | |
| 	const int sleepMillis = 5;
 | |
| 	Timestamp now;
 | |
| 	Timestamp::TimeDiff diff(Timestamp::TimeDiff(milliseconds)*1000);
 | |
| 
 | |
| 	do
 | |
| 	{
 | |
| 		try
 | |
| 		{
 | |
| 			if (tryLockImpl())
 | |
| 				return true;
 | |
| 		}
 | |
| 		catch (...)
 | |
| 		{
 | |
| 			throw SystemException("cannot lock mutex");
 | |
| 		}
 | |
| 		Sleep(sleepMillis);
 | |
| 	} while (!now.isElapsed(diff));
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| 
 | |
| FastMutexImpl::FastMutexImpl()
 | |
| {
 | |
| 	// the fct has a boolean return value under WInnNt/2000/XP but not on Win98
 | |
| 	// the return only checks if the input address of &_cs was valid, so it is safe to omit it
 | |
| 	InitializeCriticalSectionAndSpinCount(&_cs, 4000);
 | |
| }
 | |
| 
 | |
| 
 | |
| FastMutexImpl::~FastMutexImpl()
 | |
| {
 | |
| 	DeleteCriticalSection(&_cs);
 | |
| }
 | |
| 
 | |
| 
 | |
| bool FastMutexImpl::tryLockImpl(long milliseconds)
 | |
| {
 | |
| 	const int sleepMillis = 5;
 | |
| 	Timestamp now;
 | |
| 	Timestamp::TimeDiff diff(Timestamp::TimeDiff(milliseconds)*1000);
 | |
| 	do
 | |
| 	{
 | |
| 		try
 | |
| 		{
 | |
| 			if (TryEnterCriticalSection(&_cs) == TRUE)
 | |
| 				return true;
 | |
| 		}
 | |
| 		catch (...)
 | |
| 		{
 | |
| 			throw SystemException("cannot lock mutex");
 | |
| 		}
 | |
| 		Sleep(sleepMillis);
 | |
| 	}
 | |
| 	while (!now.isElapsed(diff));
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| 
 | |
| } // namespace Poco
 | 
