views:

69

answers:

3

Hello, I'm not quite sure if it's possible to do what I'm about to ask so I thought I'd ask.

I have a multi-threaded program where threads share a memory block to communicate necessary information. One of the information is termination of threads where threads constantly check for this value and when the value is changed, they know it's time for pthread_exit(). One of the threads contains listen() function and it seems to wait indefinitely. This can be problematic if there are nobody who wants to make connection and the thread needs to exit but it can't check the value whether thread needs to terminate or not since it's stuck on listen() and can't move beyond.

while(1)
{
  listen();
  ...
  if(value == 1)
    pthread_exit(NULL);
}

My logic is something like that if it helps illustrate my point better. What I thought would solve the problem is to allow listen() to wait for a duration of time and if nothing happens, it moves on to next statement. Unfortunately, none of two args of listen() involves time limit. I'm not even sure if I'm going about the right way with multi-threaded programming, I'm not much experienced at all. So is this a good approach? Perhaps there is a better way to go about it? Thanks for any insightful comments.

EDIT: just to clarify a little, the reason listen() is in the while loop is that this is a server and will be connected to multiple clients at a time.

+1  A: 

You should send a signal from the other thread (the one that changes the value to 1). It will make the listen function return with the EINTR error code.

Didier Trosset
Personnally I wouldn't complicate things with signals, threading alone is difficult enough.
Bastien Léonard
Sorry I'm rather inexperienced in multi-threading, how would I go about sending signals between threads?
Fantastic Fourier
Use pthread_kill()
Didier Trosset
A: 

IIRC you need to set the timeout with setsockopt(), and check errno after listen() fails to see if it's a timeout or a serious error.

To me it seems that it should be doable to call listen() only once if you always use the same connection socket. But maybe you'll have the same problem with accept().

Bastien Léonard
The problem is that this is a server program and is waiting (though listen()) for incoming client connections that haven't been established yet (and will establish using accept() )
Fantastic Fourier
A: 

You would set the socket to non-blocking, and wait for events using select/poll or similar - select/poll allows you to set a timeout.

Note that listen() doesn't block, it just marks the socket ready to handle incoming connecions - accept() would be the next step, that does block.

nos
I thought listen() was waiting for incoming connection? I am using select() to check packets from multiple sockets though (because this is for a server and there will be multiple clients trying to connect) and that's for already established connections.
Fantastic Fourier
@Fantastic Fourier:No, `listen()` only marks the socket as a passive "listening" socket, and returns immediately. You have to call `accept()` later to create the real connection (which may block, iff the listening socket is blocking).
slacker
Sorry, but I don't think I'm understanding it quite right. I get that I use accept() after listen() returns. If I were to use select/poll, I should discriminate whether the newly received data is from a new connection or not and then use accept() for a new connection?
Fantastic Fourier
Yes. Add the listening socket to the `readfds` set in `select()`, and if it's set when `select()` returns, then you can call `accept()` on it.
caf