информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Страшный баг в WindowsПортрет посетителя
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[win32] custom srwlock (non vista) - версия 3! new! 15.09.08 07:08  
Автор: void <Grebnev Valery> Статус: Elderman
Отредактировано 19.09.08 07:11  Количество правок: 5
<"чистая" ссылка>
Рассматривается контейнер (словарь), для которого имеются 1-2 writer и 4-5 readers. Ищется решение для реализации следуюшей политики блокировок:

- writer экслюзивно блокирует любые операции других wtiters/readers, выполняя acquireLockExclusive();
- reader не блокирует других readers, но блокирует любых writers выполняя acquireLockShared().

Ниже приводится простое решение, которое, как представляется, неплохо работает (я тестировал его на 1-4CPU компьютерах для различных OS).

class SRWLock_favor_readers3
{
public:
	void acquireLockShared()
	{
		// try lock
		while(_InterlockedIncrement(&m_writers_readers_flag) > 0xFFFF)
		{
			// rollback
			_InterlockedDecrement(&m_writers_readers_flag);
			::WaitForSingleObject(m_evt_no_writers, INFINITE);
		}
	}

	void acquireLockExclusive()
	{
		// lock writers
		::EnterCriticalSection(&m_cswriters);
		do
		{	// wait for all readers shared locks released
			while(m_writers_readers_flag != 0x0)
			{
				::Sleep(1);
			}
		}
		// doublecheck
		while( _InterlockedCompareExchange(&m_writers_readers_flag,0x1+0xFFFF,0x0) != 0x0);
		::ResetEvent(m_evt_no_writers);
	}

	void releaseLockShared()
	{
		// release reference to a reader
		_InterlockedDecrement(&m_writers_readers_flag);
	}

	void releaseLockExclusive()
	{
		// unlock readers
		_InterlockedXor(&m_writers_readers_flag, 0x1+0xFFFF);
		::SetEvent(m_evt_no_writers);

		// unlock writers
		::LeaveCriticalSection(&m_cswriters);
	}

	// lock statistics
	LONGLONG locked_acquiringLockExclusive(void) const
	{
		return 0;
	}
	LONGLONG locked_acquiringLockShared(void) const
	{
		return 0;
	}

	SRWLock_favor_readers3(): m_writers_readers_flag(0L)
	{
		::InitializeCriticalSection(&m_cswriters);
		m_evt_no_writers = ::CreateEvent(NULL, TRUE, TRUE, NULL);
	}
	
	~SRWLock_favor_readers3()
	{
		::DeleteCriticalSection(&m_cswriters);
		::CloseHandle(m_evt_no_writers);
	}

private:
	CRITICAL_SECTION m_cswriters;
	HANDLE m_evt_no_writers;
	LONG m_writers_readers_flag;
};

---

Спасибо за критику и за найденные ошибки.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach