2014-09-22 2 views
0

Я обрабатываю нестандартный модем через последовательный порт с перекрытием. Помимо чтения и записи на телекоммуникационную линию, я должен проверить контрольные линии, как CTS и DSR с использованием функции WaitCommEvent().Отмена WaitCommEvent для перекрывающихся серийных операций ввода-вывода

DWORD EvtMask; 
/// (some scopes/levels ommitted) 

const BOOL syncChange = WaitComEvent(hFile, &EvtMask, &overlapped); 
if (!syncChange) { 
    assert(GetLastError() == ERROR_IO_PENDING); 
    /// *background activity* probably writing into EvtMask 
    /// until overlapped.hEvent gets signalled 
} 

В (практически все) случаях вызов функции указывает *background activity*, я должен ждать на overlapped.hEvent произойдет. Поскольку я также жду событий из альтернативных источников (например, IPC, вызванных пользовательским вводом, завершением программы), я использую функцию WaitForMuiltipleObjects(). Но если блокировка ожидания завершена для других причин, кроме изменений в контрольной строке, как я могу остановить фоновую активность на EvtMask? Код, на котором я основан, в настоящее время использует SetCommMask(hFile, 0), но я не нашел надежной ссылки для этого.

Я также наблюдаю случаи, когда изменения в строках управления не поддерживаются должным образом (драйвер ?, VM?), Поэтому я должен выполнить нарезное ожидание с промежуточной проверкой.

Что необходимо сделать, чтобы безопасно покинуть область, в которой объявлена ​​переменная EvtMask?

+0

Вы должны вызвать CancelIo(). Пользовательский ввод обычно не является большой причиной для отмены ввода-вывода, конечно. У вас есть китайское печенье, в котором говорится, что вы полностью перепишете его. –

+0

@ HansPassant haha, есть много, чтобы переписать ... – Wolf

+0

@HansPassant Я изменил вопрос, есть еще одна (важная) причина, которую нужно учитывать. Теперь у вас больше смысла? Благодаря! – Wolf

ответ

1

код у вас есть правильно и полностью поддерживается the documentation, в котором четко сказано:

Если процесс пытается изменить маску события ручки устройства с помощью функции SetCommMask в то время как перекрывается WaitCommEvent операция в процессе, WaitCommEvent сразу возвращается.

Я использовал этот факт как для «настоящих» последовательных портов, так и для эмуляции виртуальных последовательных портов USB, и он работает надежно.

(В моем конкретном случае, я наблюдал за EV_TXEMPTY, чтобы я мог гарантировать минимальное расстояние между некоторыми передачами на проводе)

+0

Ницца, эта самая порция была * не * понятна мне. Он смешивает WaitCommEvent-вызовы, и операция запускается в фоновом режиме. Тем не менее, спасибо, что посмотрели на него. И это определенно полезно :-) – Wolf

+0

Просто крошечная деталь: после вызова 'SetCommMask' с нулевой маской вам нужно снова вызвать' WaitCommEvent'? – Wolf

+0

@Wolf: Ожидаемая операция 'WaitCommEvent' завершится немедленно (или, по крайней мере, очень скоро), не предполагайте, что у вас есть память, как только вызывается« SetCommMask'). Поэтому, если вы хотите получать уведомления еще раз, вы должны позвонить ему еще раз. –