Вверх ↑
Ответов: 4621
Рейтинг: 746
#1: 2017-05-17 12:16:31 ЛС | профиль | цитата
А-а-а, вот что оно значило.

Пока что на словах, такая мысля по поводу решения Galkov-а. Функция WaitForMultipleObjects возвращает индекс сработавшего Event. Если их несколько, то наименьший индекс. Это значит, что при активном приёме данных будет возвращаться индекс OvrRd.hEvent (=0), а не EvRdStop. Следовательно по выполнению THICOMEX.CloseCom функция WaitForMultipleObjects с высокой вероятностью завершится сигналом OvrRd.hEvent и пойдёт дальше на вызов onSyncRead (если подключен).
Так вот, вызов COMEX.doStop из главного потока пользователем (не из событий COMEX) приведёт к тому, что главный поток стаёт на thrd.WaitFor, в то время как метод THICOMEX.ExecuteRd в параллельном потоке получает сигнал не остановки, а приёма данных и блокируется на вызове Sender.Synchronize(SyncExecRd).
Можно уменьшить вероятность этого, если первым в массиве на WaitForMultipleObjects поставить EvRdStop. Тогда при одновременном срабатывании сигналов, условие if (Signaled = WAIT_OBJECT_0{=0}) then break сработает. Но: при активном приёме данных остаётся вероятность, что COMEX.doStop будет вызвано ПОСЛЕ if (Signaled = WAIT_OBJECT_0) then break, но перед Sender.Synchronize(SyncExecRd), что опять же приведёт к deadlock.
Попробую симулировать такую ситуацию, если будет время.
карма: 26

0
Редактировалось 2 раз(а), последний 2017-05-17 12:18:26