-
Выяснил что это все таки таймаут, но таймаут вне зависимости от его размера - т.е. хоть 20 секунд поставь. Переписал так:
If (GetLastError = ERROR_IO_PENDING) Then
Begin
RdRes := GetOverlappedResult(idComm, IO, Bytes, True); // А вдруг уже все?
If Not RdRes Then
Begin
WaitRes := WaitForSingleObject(IO.hEvent, 200);
RdRes := WaitRes = 0;
If (RdRes) Then
RdRes := GetOverlappedResult(idComm, IO, Bytes, True)
Else
Begin
OutputDebugString(PChar('Wait bug: ' + SysErrorMessage(GetLastError)));
End
End Else OutputDebugString('Wow');
End Else OutputDebugString(PChar('ReadFile bug'));
ээфект от этого заклинания получился странный: ошибок кажется не возникает, но и сообщение 'Wow' не выводит... Теперь придется проверить на одноядерных процессорах и на Win98 - сдается мне, что там оно себя может вести иначе...
-
А нет, все на месте :)
Если заменить
RdRes := GetOverlappedResult(idComm, IO, Bytes, True); на False, то выдает вот что:
ODS: Wait bug: Наложенное событие ввода/вывода не находится в сигнальном состоянии
Будем ломать дальше...
-
Все страньше и страньше. Таймаут теперь не возникает, но зато все как сначала: все отрабатывает Ok, но число байт = 0
Интересно еще вот что, если программа обменивается "пустыми" кадрами (там только заголовки без информации), то ошибок не возникает. Как только идет обмен "длинными" информационными кадрами возникает ошибка.
-
Дай определение "пустого" и "длинного" информационного кадра ..
-
> REA (16.05.08 10:41)
Могу переслать тебе книгу Павла Агурова. Самое, имхо лучшее пособие по работе с СОМ-портом. Скажи только куда.
-
>Дай определение "пустого" и "длинного" информационного кадра ..
ну пустой это байт 6, а длинный может 10 и более, но тоже не больше 16 наверно. Точнее не помню, но думаю это и не нужно.
>Могу переслать тебе книгу Павла Агурова. Самое, имхо лучшее пособие по работе с СОМ-портом. Скажи только куда.
Было бы здорово. Шлите на rea999<>hotmail.com
Только мне уже самому можно скоро будет книгу писать :)
-
> REA (17.05.08 20:06) [25]
Выслал.
-
> пустой это байт 6, а длинный может 10 и более
6 байт - это отнюдь не "пустой кадр".
Даже 1 байт, посланный дивайсом по прикл.протоколу, уже не есть "пустой кадр".
Может ты порт не должным образом инициализируешь ?
-
>6 байт - это отнюдь не "пустой кадр".
С точки зрения протокола кадрового уровня я имел ввиду. Поэтому в кавычках.
В синхронном режиме все работало. С появлением многоядерных компьютеров работать перестало (связано с записью и маханием DTR).
Ну может и неправильно инициализирую. Хотя 12 лет отработало уже...
Все равно непонятно где байты пропадают.
-
>Германн
Спасибо!
-
Поиграл с настройками порта - действительно при одних значениях таймаутов порта возникает именно таймаут при WaitForSingleObject, а при других таймаут не возникает, но число байт = 0
Сейчас сделал чтобы возникал таймаут (все таймауты порта установлены в 0, кроме межбайтового на чтение = 4мс). Ищем дальше...
-
А так ли уж необходим асинхронный оверлэп-режим ?
-
>А так ли уж необходим асинхронный оверлэп-режим ?
Дело в следующем: мне нужно дождаться ухода последнего байта, чтобы махнуть по протоколу DTR. Это можно сделать при помощи WaitCommEvent, но сама по себе эта функция таймаута не имеет и может зависнуть, если вызвать ее тогда, когда последний байт уже ушел. Что на многоядерных компьютерах и происходит. В Overlapped режиме можно результат проверить позже с таймаутом. Запись в порт в таком виде вроде работает.
-
Думаю, у тебя как минимум 2 верных варианта избавления от геморроя:
1. Работай с портом проверенным тобой способом, т.е. в синхронном блок-режиме, но в доп.потоке, если это непозволительно для основного.
2. Работай в оверлэпе (или с колбэками), но исключи возможность выполнения неконтролируемых тобой потоков своего процесса разными ядрами (см. SetProcess/ThreadAffinitiMask)
-
>Работай с портом проверенным тобой способом, т.е. в синхронном блок-режиме, но в доп.потоке, если это непозволительно для основного
там это и так в доп. потоке
>Работай в оверлэпе (или с колбэками)
пробую с колбэками. Насчет ThreadAffinitiMask это как то совсем уж сурово.
да в принципе оно и так работает - протокол кадры перезапрашивает, но не люблю такие фокусы - не известно как оно себя поведет на других компьютерах
-
> там это и так в доп. потоке
А зачем тогда асинхронка ? Или этот доп.поток у тебя кроме собственно транспорта еще чем-то важным озадачен ?
> Насчет ThreadAffinitiMask это как то совсем уж сурово
Ну а как ты хотел ?
На то и AffinitiMask, чтобы явно ткнуть систему носом в упомянутый запрет
-
>А зачем тогда асинхронка ?
См. [32]
ReadFileEx под 98 не работает. Попробовал под XP (+SleepEx) - где то виснет переодически...
-
> ReadFileEx под 98 не работает
Да, не работает.
Но и упомянутых проблем с мультипроцессорностью там тоже быть не может, потому что оная поддерживается лишь в NT-линейке.
-
GetOverlappedResult
Windows Me/98/95: This function works only on communications devices or on files opened using the DeviceIoControl function.
уфф... засада за засадой
-
Да тут-то вроде бы нет засады - ты же как раз с коммуникационным дивайсом работаешь ..