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).