IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 08:47
Оценка: 1 (1)
В темах:
http://rsdn.ru/forum/network/3697233.aspx
Автор: MazkoK
Дата: 08.02.10

http://rsdn.ru/forum/network/3441036.aspx
Автор: Armastab
Дата: 24.06.09

обсуждался вопрос, используют ли функции WSASend/WSARecv входные параметры _после_ прихода завершения на GetQueuedCompletionStatus, но _до_ выхода из этих функций.
Я, с некоторыми другими товарищами, активно настаивал что нет, не используют. Подразумевая, конечно, структуру OVERLAPPED, как основной объект.. хм.. динамизма И это так, её не используют.
Но есть другая проблема — структура WSABUF. Её таки держат:

If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays pointed to by the lpBuffers parameter.
http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx

Т.е. эти структуры надо создавать на стеке. Я всегда делал только так, и поэтому с проблемами нарушения доступа не сталкивался.
А вот кое-кто пихает куда не следует

Вывод: Читаем мануалы — они рулез.

З.Ы. В свете этого, хотелось бы глянуть код asio 1.4.4 из boost 1.4
Автор: awson
Дата: 09.02.10
Re: IOCP и WSABUF
От: MazkoK  
Дата: 11.02.10 10:27
Оценка:
Здравствуйте, Gomes, Вы писали:

G>Но есть другая проблема — структура WSABUF. Её таки держат:

G>Т.е. эти структуры надо создавать на стеке. Я всегда делал только так, и поэтому с проблемами нарушения доступа не сталкивался.
G>А вот кое-кто пихает куда не следует

хм, мне почему-то в приведенном абзаце из MSDN больше бросилось в глаза второе предложение:

If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays pointed to by the lpBuffers parameter.
http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx

то есть, приложения могут, а не обязаны создавать структуры на стеке.

Но факт в том, что это действительно помогло.
Re[2]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 10:31
Оценка:
Здравствуйте, MazkoK, Вы писали:

MK>то есть, приложения могут, а не обязаны создавать структуры на стеке.


Ну я и не сказал что обязаны Просто надо. Где-то в другом месте смысла нет, одни минусы.
Re: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 12:17
Оценка:
Здравствуйте, Gomes, Вы писали:

G>В темах:

G>http://rsdn.ru/forum/network/3697233.aspx
Автор: MazkoK
Дата: 08.02.10

G>http://rsdn.ru/forum/network/3441036.aspx
Автор: Armastab
Дата: 24.06.09

G>обсуждался вопрос, используют ли функции WSASend/WSARecv входные параметры _после_ прихода завершения на GetQueuedCompletionStatus, но _до_ выхода из этих функций.
G>Я, с некоторыми другими товарищами, активно настаивал что нет, не используют. Подразумевая, конечно, структуру OVERLAPPED, как основной объект.. хм.. динамизма И это так, её не используют.

Вообще интересно, что разработчики boost::asio имели в виду под приведенной в указанной теме фразой (http://www.boost.org/users/news/version_1_42_0):

* Asio:
...
o Fixed a problem with the lifetime of handler memory, where Windows needs the OVERLAPPED structure to be valid until both the initiating function call has returned and the completion packet has been delivered.
...


Речь идет именно про OVERLAPPED, а не про WSABUF.
Re[2]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 12:24
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Вообще интересно, что разработчики boost::asio имели в виду под приведенной в указанной теме фразой (http://www.boost.org/users/news/version_1_42_0):

MC>Речь идет именно про OVERLAPPED, а не про WSABUF.

Качну, попробую разобраться. Хотя думаю там дебри ещё те
Re[3]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 14:09
Оценка:
WSABUF там, конечно, на стеке. Дальнейшую обработку надо откапывать.
А вот то, что сделана разная обработка для разного завершения, уже настораживает:
    int result = ::WSASend(...

    // Check if the operation completed immediately.
    if (result != 0 && last_error != WSA_IO_PENDING)
    {
      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
      ptr.release();
    }
    else
    {
      ptr.get()->on_pending();
      ptr.release();
    }
Re[4]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 14:48
Оценка:
Здравствуйте, Gomes, Вы писали:

G>А вот то, что сделана разная обработка для разного завершения, уже настораживает:

G>
G>    int result = ::WSASend(...

G>    // Check if the operation completed immediately.
G>    if (result != 0 && last_error != WSA_IO_PENDING)
G>    {
G>      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
G>      ptr.release();
G>    }
G>    else
G>    {
G>      ptr.get()->on_pending();
G>      ptr.release();
G>    }
G>


Все правильно, в первом случае уведомления не поступит, во втором поступит.
Re: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 11.02.10 14:51
Оценка:
Здравствуйте, Gomes, Вы писали:

я WSABUF размещаю в куче и тащу адрес через поле OVERLAPPED на завершение — где и освобождаю/переразмещаю , за 9 месяце ни одного слета

тащить на завершение ВСЕ !!
Re[5]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 15:04
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

G>>А вот то, что сделана разная обработка для разного завершения, уже настораживает:

G>>
G>>    // Check if the operation completed immediately.
G>>    if (result != 0 && last_error != WSA_IO_PENDING)
G>>

MC>Все правильно, в первом случае уведомления не поступит, во втором поступит.

Так, не понял. Это ж просто обработка ошибки, причем тут "operation completed immediately"?
Re[2]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 15:06
Оценка:
Здравствуйте, Pepel, Вы писали:

P>я WSABUF размещаю в куче и тащу адрес через поле OVERLAPPED на завершение — где и освобождаю/переразмещаю , за 9 месяце ни одного слета


Удачи!

P>тащить на завершение ВСЕ !!


Да!!!
Re[6]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 15:50
Оценка:
Здравствуйте, Gomes, Вы писали:

G>>>
G>>>    // Check if the operation completed immediately.
G>>>    if (result != 0 && last_error != WSA_IO_PENDING)
G>>>

MC>>Все правильно, в первом случае уведомления не поступит, во втором поступит.

G>Так, не понял. Это ж просто обработка ошибки, причем тут "operation completed immediately"?


Притом что уведомления не будет, операция сразу завершилась с ошибкой.
Re[7]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 15:57
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Притом что уведомления не будет, операция сразу завершилась с ошибкой.


Так ведь это ошибка, это не "operation completed immediately". Данные не ушли.
Re[8]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 17:28
Оценка:
Здравствуйте, Gomes, Вы писали:

MC>>Притом что уведомления не будет, операция сразу завершилась с ошибкой.


G>Так ведь это ошибка, это не "operation completed immediately". Данные не ушли.


Ушли ли данные — это вопрос другой. Операция закончилась, ничего уже с ней связанного не будет.
Re[2]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 17:32
Оценка:
Здравствуйте, Pepel, Вы писали:

P>я WSABUF размещаю в куче и тащу адрес через поле OVERLAPPED на завершение — где и освобождаю/переразмещаю , за 9 месяце ни одного слета


Ваши 9 месяцев не отменяют утверждения в MSDN по поводу необходимости держать WSABUF до выхода из WSASend (именно до выхода из WSASend, а не до завершения операции).
Re[9]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 17:44
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Ушли ли данные — это вопрос другой. Операция закончилась, ничего уже с ней связанного не будет.


Мы как на разных языках щаз ;)

Это:
if (result != 0 && last_error != WSA_IO_PENDING)
проверка на ОШИБКУ!
Никаким "operation completed immediately" здесь не пахнет!
При "completed immediately":
1. result == 0;
2. как мы знаем завершенка приходит, и ничего дополнительно проверять не надо.
Re[10]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 17:55
Оценка:
Здравствуйте, Gomes, Вы писали:

G>Это:

G>if (result != 0 && last_error != WSA_IO_PENDING)
G>проверка на ОШИБКУ!
G>Никаким "operation completed immediately" здесь не пахнет!

А что, разве операция не завершилась? Причем ведь сразу, immediately
Тот факт, что произошла ошибка, никак не отменяет факт немедленного завершения операции.

G>При "completed immediately":

G>1. result == 0;

Это частный случай. Completed immediately and successfully
Re[11]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 18:09
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Тот факт, что произошла ошибка, никак не отменяет факт немедленного завершения операции.

MC>Это частный случай. Completed immediately and successfully :)

Ты, видимо, в контексте темы пишешь. А я вообще. Криво же написано.
Re[12]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 18:19
Оценка:
Или это такое глобальное обобщение — нет pending-а, значит immediately?
Т.е. предлагают ошибку обрабатывать в рабочем потоке.
Re[13]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 19:03
Оценка:
Здравствуйте, Gomes, Вы писали:

G>Или это такое глобальное обобщение — нет pending-а, значит immediately?

G>Т.е. предлагают ошибку обрабатывать в рабочем потоке.

А где ее еще обрабатывать, если уведомления не будет?
Все правильно у них написано.
Re[14]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 11.02.10 19:07
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>А где ее еще обрабатывать, если уведомления не будет?


Вариант с возвратом ошибки чем плох?
Re[15]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 11.02.10 20:09
Оценка:
Здравствуйте, Gomes, Вы писали:

MC>>А где ее еще обрабатывать, если уведомления не будет?


G>Вариант с возвратом ошибки чем плох?


Возвратом куда? И как это должно сменить поток?
Re[16]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 12.02.10 05:59
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Возвратом куда?


В вызывающую функцию, куда ж ещё.
DWORD Send(...)
{
    ...
    WSASend(...);
    ...
    return dwRet;
}

MC>И как это должно сменить поток?

Зачем?

Правда я с asio не работал, может там все не так как везде.
Re[3]: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 12.02.10 07:13
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Здравствуйте, Pepel, Вы писали:


P>>я WSABUF размещаю в куче и тащу адрес через поле OVERLAPPED на завершение — где и освобождаю/переразмещаю , за 9 месяце ни одного слета


MC>Ваши 9 месяцев не отменяют утверждения в MSDN по поводу необходимости держать WSABUF до выхода из WSASend (именно до выхода из WSASend, а не до завершения операции).


ок, спасибо, вот прочитал этот абзац — ведь мы на вход WSASend подаем в общем случае массив структур WSABUF (пара длина / адрес данных), меня (возможно !) спасает от слета тот факт, что этот массив у меня сознательно одноэлементный , а если у кого-то в нем сотни буферов на передачу, то тут высоковероятна шляпа — за одно завершение этот массив не отправится и значит не следует его валить на первом же завершении , т.е. предупреждение авторов документации оно для всех и на все случаи, так что ли
Re[17]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 12.02.10 09:59
Оценка:
Здравствуйте, Gomes, Вы писали:

MC>>Возвратом куда?

G>В вызывающую функцию, куда ж ещё.

Будет еще один if, теперь уже в вызывающй функции. Толку-то?
А так — обычный обработчик немедленного выполнения операции.
Не забывай, что boost::asio не ограничивается Windows. Если WSASend отправляет уведомление всегда, даже в случае немедленного выполнения, то для методов на других системах (kqueue, epoll, ...) это [может быть] не так.

MC>>И как это должно сменить поток?

G>Зачем?

Ты возмущался, что они-де "предлагают ошибку обрабатывать в рабочем потоке".
Re[4]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 12.02.10 10:04
Оценка:
Здравствуйте, Pepel, Вы писали:

P>а если у кого-то в нем сотни буферов на передачу, то тут высоковероятна шляпа — за одно завершение этот массив не отправится и значит не следует его валить на первом же завершении


Уведомление о завершении операции одно и только одно на операцию, вне зависимости от количества структур WSABUF.

А спасает тебя скорее всего конкретная реализация [на конкретной версии Windows], которая на самом деле не трогает WSABUF после начала операции. Но нет гарантии, что эта реализация не меняется (или не будет меняться) от версии к версии.
Re[5]: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 12.02.10 10:30
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Уведомление о завершении операции одно и только одно на операцию, вне зависимости от количества структур WSABUF.


э-э-э-э, стоп, прямой зависимости нет , но так понимаю чем больше данных ставим на передачу (вот тот же массив WSABUF погуще), тем все таки вероятней, что сетевая подсистема будет отсылать их частями и уведомлений о завершении операции будет более одного
Re[6]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 12.02.10 10:37
Оценка:
Здравствуйте, Pepel, Вы писали:

MC>>Уведомление о завершении операции одно и только одно на операцию, вне зависимости от количества структур WSABUF.


P>э-э-э-э, стоп, прямой зависимости нет , но так понимаю чем больше данных ставим на передачу (вот тот же массив WSABUF погуще), тем все таки вероятней, что сетевая подсистема будет отсылать их частями и уведомлений о завершении операции будет более одного


Еще раз. ОДНО И ТОЛЬКО ОДНО.
Re[7]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 12.02.10 10:53
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>ОДНО И ТОЛЬКО ОДНО.


Тут даже я чуть в штаны не наделал!!
Re[18]: IOCP и WSABUF
От: Gomes Россия http://irazin.ru
Дата: 12.02.10 11:02
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Будет еще один if, теперь уже в вызывающй функции. Толку-то?

MC>А так — обычный обработчик немедленного выполнения операции.

Я к тому, что сложная функция должна вернуть код ошибки, а не выдавать его через хитрый механизм.
А если после Send() надо выполнить код, зависящий от этого?

MC>Ты возмущался, что они-де "предлагают ошибку обрабатывать в рабочем потоке".


Угу. Считаю, это ненормально.
Re[7]: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 12.02.10 11:55
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Здравствуйте, Pepel, Вы писали:


MC>>>Уведомление о завершении операции одно и только одно на операцию, вне зависимости от количества структур WSABUF.


P>>э-э-э-э, стоп, прямой зависимости нет , но так понимаю чем больше данных ставим на передачу (вот тот же массив WSABUF погуще), тем все таки вероятней, что сетевая подсистема будет отсылать их частями и уведомлений о завершении операции будет более одного


MC>Еще раз. ОДНО И ТОЛЬКО ОДНО.


вот это подозреваю действительно платформозависимое утверждение
Re[8]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 12.02.10 12:20
Оценка:
Здравствуйте, Pepel, Вы писали:

P>>>э-э-э-э, стоп, прямой зависимости нет , но так понимаю чем больше данных ставим на передачу (вот тот же массив WSABUF погуще), тем все таки вероятней, что сетевая подсистема будет отсылать их частями и уведомлений о завершении операции будет более одного


MC>>Еще раз. ОДНО И ТОЛЬКО ОДНО.


P>вот это подозреваю действительно платформозависимое утверждение


Отнюдь. На этом, собственно, все и работает. Один вызов ввода-вывода — одно и только одно уведомление.
Re[9]: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 12.02.10 12:33
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Отнюдь. На этом, собственно, все и работает. Один вызов ввода-вывода — одно и только одно уведомление.


кабы так зачем тогда GetQueuedCompletionStatus() второй параметр :

lpNumberOfBytes
[out] Pointer to a variable that receives the number of bytes transferred during an I/O operation that has completed.

если всегда одно срабатывание на один инициатор отсылки/приема ?

можно было бы думать, что на случай когда частичная отсылка — результат отказа на транспорте и нам надо знать что таки ушло (зачем ??) , но таки это нигде не сказано, вот уже где действительно лучше перестраховаться если нет прямых указаний вести себя так или иначе
Re[10]: IOCP и WSABUF
От: Michael Chelnokov Украина  
Дата: 12.02.10 12:46
Оценка:
Здравствуйте, Pepel, Вы писали:

MC>>Отнюдь. На этом, собственно, все и работает. Один вызов ввода-вывода — одно и только одно уведомление.


P>кабы так зачем тогда GetQueuedCompletionStatus() второй параметр :


P>lpNumberOfBytes

P>[out] Pointer to a variable that receives the number of bytes transferred during an I/O operation that has completed.

P>если всегда одно срабатывание на один инициатор отсылки/приема ?

P>можно было бы думать, что на случай когда частичная отсылка — результат отказа на транспорте и нам надо знать что таки ушло (зачем ??) ,

Именно для этого. Только больше не для write/send, а для read/recv. Там необходимость этого параметра, надеюсь, очевидна.

P>но таки это нигде не сказано,


Про возможность чтения/записи меньшего количества байт, нежели запрошено, сказано в описании любой функции ввода-вывода.

P>вот уже где действительно лучше перестраховаться если нет прямых указаний вести себя так или иначе


Когда Вы взлетаете на самолете, тоже рассчитываете сесть несколько раз, если лететь далеко?
Re[11]: IOCP и WSABUF
От: Pepel Беларусь  
Дата: 12.02.10 13:45
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>Здравствуйте, Pepel, Вы писали:


MC>>>Отнюдь. На этом, собственно, все и работает. Один вызов ввода-вывода — одно и только одно уведомление.


P>>кабы так зачем тогда GetQueuedCompletionStatus() второй параметр :


P>>lpNumberOfBytes

P>>[out] Pointer to a variable that receives the number of bytes transferred during an I/O operation that has completed.

P>>если всегда одно срабатывание на один инициатор отсылки/приема ?

P>>можно было бы думать, что на случай когда частичная отсылка — результат отказа на транспорте и нам надо знать что таки ушло (зачем ??) ,

MC>Именно для этого. Только больше не для write/send, а для read/recv. Там необходимость этого параметра, надеюсь, очевидна.


P>>но таки это нигде не сказано,


MC>Про возможность чтения/записи меньшего количества байт, нежели запрошено, сказано в описании любой функции ввода-вывода.


P>>вот уже где действительно лучше перестраховаться если нет прямых указаний вести себя так или иначе


MC>Когда Вы взлетаете на самолете, тоже рассчитываете сесть несколько раз, если лететь далеко?


ок, спасибо!!, Михаил я все-таки не поленюсь и вкатаю строчку логирования для ситуации порциональной отсылки посредством WSASend в несолько срабатываний GetQueuedCompletionStatus(), модуль (смс-рассылка) плотно работает круглосуточно и мож когда порадует а я тогда вас порадую
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.