I have a C++ DLL written in Visual Studio for use on Windows 7 using Boost 1_53_0.  The following two functions, CREATE & DESTROY, are called to launch and shutdown a simple ZeroMQ server (code below).  The thread is launched and the server on that thread goes into a continuous listening loop (as intended).  When it comes time to shut down the server then the thread is interrupted to cause thread termination (though I cannot tell if the interrupt is actually working as I get no output from the catch block).  The boost::thread object is then deleted.  Problem is that the 3rd party application which this DLL is designed for is prone to crashing after DESTROY is called and I think it’s because either the boost::thread resources are not being freed/cleared up properly or the boost::thread is not interrupting.  Have I properly handled thread instantiation, interruption and object destruction here?

 

With thanks,

 

Riskybiz.

 

 

static bool createCalled = false;//initialise static variable

static bool destroyCalled = false;//initialise static variable

static boost::thread *serverThread = nullptr;

 

int __stdcall CREATE()

{

if(createCalled == false)

{

createCalled = true;

OutputDebugStringA("TestDataAccess: CREATE");

serverThread = new boost::thread(ListenOnReplySocket);//create instance of boost::thread object

return 0;

}

return 1;

}

 

 

int __stdcall DESTROY()

{

if(createCalled == true && destroyCalled == false)

{

destroyCalled = true;

OutputDebugStringA("TestDataAccess: DESTROY");

serverThread->interrupt();//set flag for interruption

delete serverThread;

return 0;

}

return 1;

}

 

 

Simple ZeroMQ server:

 

#ifndef ZMQ_COMMUNICATIONS_H//if not defined already

#define ZMQ_COMMUNICATIONS_H//then define it

 

#define _WINSOCK2API_ //stops windows.h including winsock2.h

 

#include <zmq.hpp>

#include "boost\thread.hpp"

 

int ListenOnReplySocket()

{

//  Prepare our context and socket

    zmq::context_t context (1);

    zmq::socket_t socket (context, ZMQ_REP);

    socket.bind ("tcp://*:5555");

 

boost::this_thread::interruption_enabled();

 

try

{

while (true)

{

        zmq::message_t request;

 

        //  Wait for next request from client

        socket.recv (&request);

 

char buffer[50];

int j;

j = sprintf_s(buffer, 50, "TestDataAccess: ZMQComms: Hello");

OutputDebugStringA(buffer);

      

 

        //  Do some 'work'

        Sleep (1000);

 

        //  Send reply back to client

        zmq::message_t reply (5);

        memcpy ((void *) reply.data (), "World", 5);

        socket.send (reply);

 

boost::this_thread::interruption_point();//check iterruption flag

 

}

}

catch(boost::thread_interrupted)

{

char buffer[100];

int j;

j = sprintf_s(buffer, 100, "TestDataAccess: ZMQComms: Server Thread Interrupted");

OutputDebugStringA(buffer);

 

return 0;

}

 

}

#endif