Galkov писал(а):
Моя мысль пока такая: CloseCom состоит только из установки Event-а на закрытие одного из потоков.
Он, выйдя из "вечного цикла", устанавливает Event на закрытие другого потока.
Который, в свою очередь выйдя из "вечного цикла", убивает файл (CloseHandle(hFile)).
Позволю себе сформулировать общий принцип проще: Если некоторый объект используется несколькими потоками, то (при поставленой задаче неблокирующего взаимодействия потоков) уничтожением этого объекта должен заниматься тот, кто последний решил его уничтожить. Эта задача не решается с помощью критических секций - так как таким "общим объектом" будет являться сама критическая секция, кроме того она является источником блокировок.
Решается же эта задача путём реализации в таком общем объекте механизма подсчета ссылок.
Озвучу термины:
- "освобождение объекта" - в привычных нам методах программирования - вызов Free/Destroy. В случае совместного доступа нескольких потоков вызов Destroy одним потоком недопустим, пока этот объект используется в других потоках. В контексте объекта с подсчетом ссылок - уменьшение счетчика ссылок, который, достигнув 0 уничтожит объект по Destroy.
- "владелец объекта" - объект (или поток), метод которого отвечает за уменьшение счетчика ссылок совместного объекта (освобождение). Первым владельцем объекта становится тот, кто его создаёт - тут других вариантов нет. Он может передать этот объект во владение кому-то другому, затем сразу же забыть о его существовании (так как новый владелец будет отвечать за уничтожение нашего объекта и может его уничтожить). Если же владелец хочет использовать объект одновременно с другими потоками, то только владелец может передать его кому-то другому, предварительно увеличив счетчик использования объекта. Таким образом владелец получает гарантию, что совместный объект не будет уничтожен ни одним из владельцев, пока каждый владелец заинтересован в его существовании.
В Pipe-сервере это выглядит так:
Ну, а CloseHandle(hFile) по идее прерывает WaitForSingleObject, и последующие функции работы с этим хендлом показывают соответствующую ошибку - достаточно правильно обработать.