0
votes

I'm writing an extension to MFC app with use of ZMQ (zmq.hpp). When I'm trying to unload my DLL from the app, the zmq_ctx_destroy() function hangs forever.

I have found a similar issue but there is no answer.

I've tried to debug it and found out that it stops in function zmq::thread_t::stop() on the first line:

DWORD rc = WaitForSingleObject (descriptor, INFINITE);

It hung even without sending anything. Simplified code looks like this:

zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.connect(ENDPOINT.c_str());

Socket and context destroyed when leaving scope.

Call Stack:

libzmq-v100-mt-gd-4_0_4.dll! zmq::thread_t::stop()  Line 56 + 0x17 bytes    C++ 
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::~select_t()  Line 57 + 0x13 bytes   C++ 
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::`scalar deleting destructor'()  + 0x2c bytes    C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::~io_thread_t()  Line 39 + 0x37 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::`scalar deleting destructor'()  + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::~ctx_t()  Line 82 + 0x49 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::`scalar deleting destructor'()  + 0x2c bytes   C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::terminate()  Line 153 + 0x3d bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_term(void * ctx_)  Line 171 + 0xa bytes    C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_destroy(void * ctx_)  Line 242 C++
DataReader.dll! zmq::context_t::close()  Line 309 + 0xe bytes   C++
DataReader.dll! zmq::context_t::~context_t()  Line 303  C++

The MFC app has a mechanism to run specifically created DLLs. This DLL is based on CWinApp, all DLL-specific initialization code in the InitInstance member function and termination code in ExitInstance. So this JIRA issue should not be the case.

After a couple of days I found out that the app also relies on sockets as ZMQ. So at the end of its life ZMQ context was waiting for closing of all opened sockets in the process, but MFC app continues to use its opened sockets. That was the reason why zmq_ctx_destroy() function hangs forever.

1
That's a bug report for ZMQ or MFC not a question for SO, IMHO. Anyhow, sources for both are available, so feel free to debug the problem. I think that ZMQ uses a few globals, those are the ones I would take a look at, they caused issues in other environments as well.Ulrich Eckhardt
DllMain entry point: "Warning There are significant limits on what you can safely do in a DLL entry point. See General Best Practices for specific Windows APIs that are unsafe to call in DllMain."IInspectable

1 Answers

-1
votes

Solution for cases like this one (when app uses sockets as well and you need to add some functionality based on ZMQ). Create a new process. This process will create a ZMQ context and send/receive all messages. Data from dll could be passed to that process via Windows messages or shared memory.