WSACleanup блокируется ???
От: pankov  
Дата: 17.09.04 05:19
Оценка:
попробую сформулировать проблему:
есть приложение-сервер (с клиентом никаких проблем нет).
сервер в зависимости от режима работы (обычное приложение или NT сервис) запускает нужную dll в нужном режиме.
так вот реализация работы с сокетами (TCP соединение с клиентами) в сервере находится в dll.
в dll имеется класс с конструктором и деструктором, понятное дело, в которых вызываются WSAStartup и WSACleanup соответственно.
в этой же dll имеется еще один класс работы с другим сокетом (UDP соединение с внешней железякой — коммутационная станция КСМ-400 через Ethernet).
там такой же почти конструктор и деструктор с теми же WSAStartup и WSACleanup (это для того чтоб можно этот класс в других приложениях применять).
ну и вобщем все это работает и взаимодействует между собой. Работает все прекрасно.
Проблема заключается в том, что при закрытии сервера (при вызове деструкторов, и надо сказать что выше описанные классы являются базовыми для некоего потомка через множественное наследование, то есть деструкторы вызываются один за другим сразу) происходит удачное выполнение первого вызова WSACleanup и блокируется второй вызов WSACleanup.
При этом первые два вызова WSAStartup из конструкторов проходят очень спокойно (нормально).
Вобщем схема такая :
1. WSAStartup
2. WSAStartup
3. создаются сокеты
4. какая то работа в потоках с сокетами
5. закрываются сокеты
6. WSACleanup
7. WSACleanup

из-за этого трабла в среднем на четвертое-пятое закрывание приложения происходит deadlock потока (там где деструкторы).
то есть иногда все нормально закрывается, а иногда просто заговор какой-то. В WSACleanup входит и замирает.
В чем может крыться проблема ???

VC++6.0 SP5 (NOT MFC,ATL or other libs) only Win32API
Windows2000 Pro SP4 eng (WS2_32.DLL)
Re: WSACleanup блокируется ???
От: butcher Россия http://bu7cher.blogspot.com
Дата: 17.09.04 05:26
Оценка:
Здравствуйте, pankov, Вы писали:

P>из-за этого трабла в среднем на четвертое-пятое закрывание приложения происходит deadlock потока (там где деструкторы).

P>то есть иногда все нормально закрывается, а иногда просто заговор какой-то. В WSACleanup входит и замирает.
P>В чем может крыться проблема ???

Почитайте этот
Автор: Michael Chelnokov
Дата: 24.01.03
топик, может поможет.
Вот ещё MSDN:

If an application needs to quit while a blocking call is outstanding, the application must first cancel the blocking call with WSACancelBlockingCall then issue the WSACleanup call once control has been returned to the application.


Нет ничего невозможного..
Re[2]: WSACleanup блокируется ???
От: pankov  
Дата: 17.09.04 07:01
Оценка:
Здравствуйте, butcher, Вы писали:

B>Почитайте этот
Автор: Michael Chelnokov
Дата: 24.01.03
топик, может поможет.


это я читал собственно так оно и сделано...

B>Вот ещё MSDN:

B>

B>If an application needs to quit while a blocking call is outstanding, the application must first cancel the blocking call with WSACancelBlockingCall then issue the WSACleanup call once control has been returned to the application.


и с MSDNом я тоже дружу . WSACancelBlockingCall относится к старой реализации винсокетов. Пробовал я делать этот вызов, но помочь он ничем не смог...

Наблюдается следующая картинка :

я вызвал shutdown и closesocket для всех сокетов, но иногда потоки в которых проходят прослушивание, чтение и запись не завершаются. А завершаться они должны по принципу : возвратилась ошибка, выйти из потока. Видимо не всегда происходят выходы. Забыл я еще упомянуть о факте работы rpc в сервере. Возможно rpc как то влияет и блокирует WSACleanup. Старый добрый MSDN не содержит к сожалению решений подобных ситуаций...

Может прибиение rpc как то блокирует сокеты приложения ??? Но почему первый WSACleanup проходит хорошо (он кстати пока не выгружает ws2_32.dll, а только лишь декремент выполняет), а второй блокируется (вот этот и выполняет выгрузку ws2_32.dll). Стоит отметить, что ранее я прибивал потоки через TerminateThread, но потом следуя рекомендации Дж.Рихтера сделал выход из потока внутри через rerurn. Раньше это все работало без rpc. Но пришла беда на нашу землю и .... о чем это я ?
Re[3]: WSACleanup блокируется ???
От: Аноним  
Дата: 17.09.04 07:10
Оценка: +1
Здравствуйте, pankov, Вы писали:


P>Наблюдается следующая картинка :


P>я вызвал shutdown и closesocket для всех сокетов, но иногда потоки в которых проходят прослушивание, чтение и запись не завершаются. А завершаться они должны по принципу : возвратилась ошибка, выйти из потока. Видимо не всегда происходят выходы. Забыл я еще упомянуть о факте работы rpc в сервере. Возможно rpc как то влияет и блокирует WSACleanup. Старый добрый MSDN не содержит к сожалению решений подобных ситуаций...


P>Может прибиение rpc как то блокирует сокеты приложения ??? Но почему первый WSACleanup проходит хорошо (он кстати пока не выгружает ws2_32.dll, а только лишь декремент выполняет), а второй блокируется (вот этот и выполняет выгрузку ws2_32.dll). Стоит отметить, что ранее я прибивал потоки через TerminateThread, но потом следуя рекомендации Дж.Рихтера сделал выход из потока внутри через rerurn. Раньше это все работало без rpc. Но пришла беда на нашу землю и .... о чем это я ?


скорее всего ошибка где-то у Вас в приложении

по shutdown() и closesocket() должны вывалится все блокирующие send() и recv()
по closesocket() должны вывалится все блокирующие accept()
дождитесь завершения рабочих потоков WaitForSingleObject() WaitForMultipleObjects()
потом уже закрывайте winsock, лучше это делать не в каждом объекте, все-таки,
хотя если объект статический и живет все время работы программы, то можно.

кстати говоря, не всегда, к примеру, recv() вернет ошибку, может вернуть и EOF
(т.е. return не SOCKET_ERROR а 0 — тоже значит партнер закрылся)
Re[4]: WSACleanup блокируется ???
От: explorus Россия  
Дата: 23.03.05 12:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>скорее всего ошибка где-то у Вас в приложении


А>по shutdown() и closesocket() должны вывалится все блокирующие send() и recv()

А>по closesocket() должны вывалится все блокирующие accept()
А>дождитесь завершения рабочих потоков WaitForSingleObject() WaitForMultipleObjects()
А>потом уже закрывайте winsock, лучше это делать не в каждом объекте, все-таки,
А>хотя если объект статический и живет все время работы программы, то можно.

А>кстати говоря, не всегда, к примеру, recv() вернет ошибку, может вернуть и EOF

А>(т.е. return не SOCKET_ERROR а 0 — тоже значит партнер закрылся)

Ошибка была в том, что паралельно еще механизм RPC использовался (тама тоже сокеты как будто бы)
Вобщем, это дело блокирует каким то образом WSACleanup
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.