Есть программка которая работает асинхронно с СОМ портом.
Есть два потока, один обрабатывающий чтение с порта постоянно, второй который осуществляет алгоритм собственно, иногда решая кое чего в порт записать....
При чтении с помощью синхронизационного события передается сообщение о прочтении очередной порции данных и все данные передаются в главный поток.
В момент времени С когда главный поток решает записать в порт что-либо, делается следующее.
Запускается событие (Эвент) который сообщает ждущему на чтении потоку, что ему надо бы уйти в суспенд освободив очередь...
Т.е. код запроса на чтение выглядит так:
SetEvent(pMain->GetWriteEvent());
WaitForSingleObject(pMain->GetSinchronizeEvent(), INFINITE);
ResetEvent(pMain->GetSinchronizeEvent());
Т.е. изначально посылается сообщение о требовании записи в порт, после чего поток садиться на ожидание синхронизационного события, которое сообщит об успешном освобождении потоком чтения ресурса.
Вот код потока чтения в момент прихода эвента о требовании на запись:
if (resWait == WAIT_OBJECT_0+1)
{
ResetEvent(arrHandles[1]);
if (!param->type)
{
CancelIo(hcPort);
SetEvent(pMain->GetSinchronizeEvent());
SuspendThread(pMain->mSerial.GetMasterThread());
}
}
Т.е. поток ресетит событие о требовании на запись для слеующего раза.
Все опреации стоящии в PENDING режиме удаляет.
Выставляет синхронизационный эвент для продолжения работы на запись.
Сам уходит в суспенд, дабы не мешать процессу записи в порт.
Что происходит далее.
Далее просыпается главный поток получив сообщение синхронизации.
Он активизирует запись в файл так:
hMaster = pMain->mSerial.GetHandle(pMain->mSerial.GetSerialMasterPort());
masterOv = pMain->mSerial.GetOverlapped(pMain->mSerial.GetSerialMasterPort());
if (!WriteFile(hMaster, cmdLine,strlen(cmdLine),&read,masterOv))
{
err = GetLastError();
if (err != ERROR_IO_PENDING)
{
SendMessage(pMain->m_hWnd,WM_ERROR_THREAD_EXIT,0,0);
param->st = (STATES)0;
break;
}
}
resWait = WaitForSingleObject(masterOv->hEvent, INFINITE);
if (resWait != WAIT_OBJECT_0)
{
SendMessage(pMain->m_hWnd,WM_ERROR_THREAD_EXIT,0,0);
param->st = (STATES)0;
break;
}
//GetQueuedCompletionStatus(hMaster,&read,&key,&masterOv,INFINITE);
ResetEvent(masterOv->hEvent);
if (!WriteFile(hMaster, "\r\n",2,&read,masterOv) )
{
if (err != ERROR_IO_PENDING)
{
SendMessage(pMain->m_hWnd,WM_ERROR_THREAD_EXIT,0,0);
param->st = (STATES)0;
break;
}
}
resWait = WaitForSingleObject(masterOv->hEvent, INFINITE);
if (resWait != WAIT_OBJECT_0)
{
SendMessage(pMain->m_hWnd,WM_ERROR_THREAD_EXIT,0,0);
param->st = (STATES)0;
break;
}
ResetEvent(masterOv->hEvent);
ResumeThread(pMain->mSerial.GetMasterThread());
Т.е. считываются необходимые HANDLE'S, стартует асинхронная запись в порт, после чего на событие в оверлаппед струкутуре ставится ожидание.
По идее после отработки всего действа после прихода сообщения об окончании записи в порт, у меня поток получит событие о окончании статуса PENDING запись продолжится до момента полной передачи команды в порт, после чего поток перейдет к следующей команде предварительно оживив поток чтения с помощью ResumeThread. Однако хуюшки вашей дунюшке.
Никакого результата не получаем до тех пор, пока эта
ужас не отработает чтение с порта. Т.е. ни очередь не чистится ничерта.
При этом запись в порт с потока чтения вполне активна и проходит нормально.
Это уже сутки тупости подобной, сил моих больше нет смотреть на убогость майкрософта создать нечто асинхронное.
Но задачку надо решить.
Что я делаю не так? Чего еще эта манда хочет от программы, дабы осуществить посылку отложенной операции???