информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetСетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Линуксовый ботнет, распространяющийся... 
 Конец поддержки Internet Explorer 
 Рекордное число уязвимостей в 2021 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[Win32] простой вопрос по iocp 20.08.08 09:56  Число просмотров: 1748
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Хорошо бы получить ответ на один маленький давнишний вопрос... Не задавал его раньше, поскольку и так работает... Есть функция, которая весьма стандартно "вычитывает" данные из overlapped socket (впрочем не важно что это сокет - это может быть любой oveplapped хендл)

bool read(DWORD bytes_to_read)
{
	if (m_io_status == IOSTATUS_NOOP|m_io_status == IOSTATUS_COMPLETED)
	{
		// reset counters and start reading
		::ZeroMemory( get_overlapped(), sizeof(OVERLAPPED)); //reset overlapped
		m_bytes_done = 0;			// how many bytes we've received
		m_bytes_left = bytes_to_read;	// how many bytes we have left to receive
	}
	else if (m_io_status == IOSTATUS_PENDING|m_io_status == IOSTATUS_COMPLETED_SYNCHRONOUSLY)
	{
		DWORD async_done = (DWORD) get_overlapped()->InternalHigh;
		m_bytes_done += async_done;
		m_bytes_left -= async_done;
		
		if ( 0 == m_bytes_left)
		{
			// reading is completed
			m_io_status = IOSTATUS_COMPLETED;
			return true;
		}
		else if (m_io_status == IOSTATUS_PENDING)
		{
			// continue reading asynchronous results
			return true;
		}
		else
		{
			// queue next overlapped operation
		}
	}
	else
	{
		m_io_status = IOSTATUS_ERROR;
		return false;
	}
	
	// queue next overlapped operation
	if ( read((LPBYTE)m_buffer + m_bytes_done, m_bytes_left) )
	{
		// completed synchronously
		m_io_status = IOSTATUS_COMPLETED_SYNCHRONOUSLY;
		return true;
	}
	else
	{
		DWORD err = ::GetLastError(); 
		if (err == ERROR_IO_PENDING )
		{
			// operation will complete in the future
			m_io_status = IOSTATUS_PENDING;
			return true;
		}  
		else
		{
			m_io_status = IOSTATUS_ERROR;
			return false;
		}
	} 
}

---

Это работает нормально. Хотелось бы чуток лучше - если операция заканчивается синхронно (см. m_io_status = IOSTATUS_COMPLETED_SYNCHRONOUSLY), то получив сразу же ! данные, я их не обрабатываю, поскольку IOCP всё равно поместит соответствующий completion status в очередь.

Хотелось бы сделать что-нить типа (вычитывать данные, которые драйвер вернул синхронно, сразу же)

	while ( read((LPBYTE)m_buffer + m_bytes_done, m_bytes_left) )
	{
		// completed synchronously
		m_io_status = IOSTATUS_COMPLETED_SYNCHRONOUSLY;

		DWORD async_done = (DWORD) get_overlapped()->InternalHigh;
		m_bytes_done += async_done;
		m_bytes_left -= async_done;
		
		if ( 0 == m_bytes_left)
		{
			// reading is completed
			m_io_status = IOSTATUS_COMPLETED;
			return true;
		}
	}

	DWORD err = ::GetLastError(); 
	if (err == ERROR_IO_PENDING )
	{
		// operation will complete in the future
		m_io_status = IOSTATUS_PENDING;
		return true;
	}  
	else
	{
		m_io_status = IOSTATUS_ERROR;
		return false;
	}

---

Не работает ... Данные завершения синхронных операций "портятся" последующими вызовами GetQueuedCompletionStatus. Проблема в том, что для операций, которые queued на IOCP, и завершились синхронно, IOCP всё равно поставит соответстуючие issues в свою очередь. Так что следующие вызовы GetQueuedCompletionStatus будут продолжать возвращать данные которые уже были получены.

Это можно побороть?

Спасибо !
<programming> Поиск 






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


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