On Wednesday, 27 March 2013 at 20:16:39 UTC, Martin Drašar wrote:
Dne 27.3.2013 18:51, Tim napsal(a):
That works as expected, except the fact that pressing CTRL+C which stops
the while(!stopServer) doesn't terminate the mainloop in my
Connection-class (run()-method). This thread is blocked because of the receive()-method... but how can I force this thread to exit? Is there any chance to do that? I already tried to set the accepted socket to
blocking(false) without any success...

Thanks in advance for any reply!

Hi Tim,

you have to pass the termination information to the thread. It does not know about it and waits for receive() to return.

You will have to employ the select() call to some extent.

1) You can have some form of global variable that indicates termination or you can send the termination info using Tid.send(). The code can then look like this:

threadSocket.blocking(false);
auto ss = new SocketSet();
while (!shouldEnd)
{
  ss.reset();
  ss.add(threadSocket);

  auto rc = Socket.select(ss, null, null, dur!"msecs"(timeout));
  if (rc == 1)
  {
    // process your data
  }
}

And it would take at most timeout miliseconds for thread to react to termination message.

2) Use what Sean Kelly wrote. Either using a pipe or socketpair.

Martin

Thanks! I've never used message passing and I'm currently a bit confused how it works (I came from the Java-area where message passing isn't necessary for something like that)... are there any information/examples about message passing? I sill can't get it to work... I changed my code as follows:

class Connection : Thread {
        private Socket pSocket;
        void run() {
                ptrdiff_t received;
                ubyte[0x10] buffer;

                SocketSet ss = new SocketSet();

                mainloop:
                while(!stopServer) {

                        ss.reset();
                        ss.add(pSocket);

                        if (Socket.select(ss, null, null, dur!"msecs"(10)) > 0) 
{

                                received = pSocket.receive(buffer);

                                // do some more stuff here
                                if (buffer[0 .. received] == "QUIT")
                                        break mainloop;
                        }
                }
        }
        this(Socket s) {
                super(&run);
                pSocket = s;
        }
}

extern(C) void terminateServer(int s) {
        stopServer = true;
}

private bool stopServer = false;

void main() {

        sigaction_t sig;
        sig.sa_handler = &terminateServer;
        sigemptyset(&sig.sa_mask);
        sig.sa_flags = 0;
        sigaction(SIGINT, &sig, null);

        TcpSocket s = new TcpSocket();
        s.bind(new InternetAddress(2100));
        //s.blocking(false);
        s.listen(0);

        SocketSet ss = new SocketSet();

        while(!stopServer) {

                ss.reset();
                ss.add(s);

                if (Socket.select(ss, null, null, dur!"msecs"(10)) > 0)
                        (new Connection(s.accept)).start();
        }

        writeln("Server stopped");

        s.shutdown(SocketShutdown.BOTH);
        s.close();

}

Alright... let's connect to the server... the server accepts, creates an instance of Connection and starts a new thread. Now... I set stopServer to true (CTRL+C). This should stop the server and I also get the message in my main()-method that the server stopped. But the other thread (Connection-thread) doesn't terminate... it runs as long as the connection to the client is alive... by killing the connection from the client-side, the connection thread also terminates (and throws an exception).

Reply via email to