• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1029
  • Last Modified:

How to stop recvmsg from waiting

Hi,

Here is the problem, i have an application that talks to the kernel through a netlink socket. The application receives messages from the kernel throught a dedicated thread that does:

while (1){
     recvmsg(socket, msg, 0);
     process_msg(msg);
}

This works well until I have to stop the application and can't manage to stop the thread since it is still waiting for a message from the kernel. Is there a wake up recvmsg without there being a msg? I don't really want to change to a non-blocking socket if there's a way around this.

All this is in C.

Cheers.
0
goloap
Asked:
goloap
  • 5
  • 5
  • 3
  • +1
1 Solution
 
Anthony2000Commented:
You can send a signal to the thread. See:
http://manpages.courier-mta.org/htmlman7/signal.7.html
0
 
Anthony2000Commented:
You can probably use SIGUSR1.
0
 
Anthony2000Commented:
Sorry for not finishing my thought in one message.

You would then test the return value of recvmsg and if it is -1 then next look at errno and make sure it contains EINTR, see: http://linux.about.com/library/cmd/blcmdl2_recvmsg.htm
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Infinity08Commented:
Let me get this right : you want to use a blocking socket, but still want all the functionality of a non-blocking socket ? Think about that for a moment, and you'll see that it doesn't make sense ...

I would suggest using a non-blocking socket. Then the recvmsg will return -1 (with EAGAIN or EWOULDBLOCK error) when there's nothing to receive. You can then simply wait for a short period of time (short enough to allow a fast response when you want to end the thread, but long enough not to waste too much resources), and try again.
0
 
Duncan RoeSoftware DeveloperCommented:
You can use select(2) or poll(2) to wait in an interruptible fashion until the socket has data available. When you say "stop" the application, you do mean kill it don't you?
Even if not, you could actually select() on 2 file units: 1 is netlink and the other could be a pipe (named or otherwise). Then if the master thread wants to stop your netlink thread it could write a byte to the pipe. netlink-reading thread wakes up from its select() and realize it has been requested to stop.
0
 
Duncan RoeSoftware DeveloperCommented:
PS to avoid issues with blocking on opening named pipes, always open them O_RDWR
0
 
Anthony2000Commented:
Is it a bad idea to use a signal? In the past I have used both infinity08's and duncan_roe's, but I always wanted to be able get control without using a polling method. I wanted a means to interrupt the recvmsg function. I thought a signal may do the trick. What I don't exactly know is if this is a good programming technique.
0
 
Infinity08Commented:
Sending a signal is a quick-and-dirty way, because it doesn't allow to properly close all connections, and free all other resources. It would work yes, but it's not very clean ...

Just a note : polling is not bad, as long as you set the interval to a good value (not too low, not too high).
0
 
Infinity08Commented:
>> Sending a signal is a quick-and-dirty way, because it doesn't allow to properly close all connections

Unless you have a signal handler to gracefully close down of course.
0
 
Anthony2000Commented:
So, with a proper signal handler, using a signal such as SIGUSR is okay?
0
 
Infinity08Commented:
>> So, with a proper signal handler, using a signal such as SIGUSR is okay?

It might be difficult to create a proper signal handler, depending on the design of your application (especially if you're dealing with threads). But yes, assuming that your signal handler releases all resources gracefully before ending the application, then it's ok.

It's easier and less error-prone to just do some polling though ;)
0
 
Duncan RoeSoftware DeveloperCommented:
I would not use a signal for this purpose when there is another method available (like sending a byte on a pipe). You really want to clan up as part of the thread's main logic, which should be straightforward: a byte came in on the "other" fd so clean up. Signals are ... well I don't think you want to go there.
0
 
billtouchCommented:
Signals can produce hard to track down errors. Then, if you use threads, you have multiplied your troubles greatly. In these situations, I use select(). Read the man pages and see if this is what you want. I think it will do exactly what you want to happen.

With all respect to Infinity08, what he says is true, but I find the two words signal and graceful hard to take in the same sentence.

Bill
0
 
Infinity08Commented:
>> With all respect to Infinity08, what he says is true, but I find the two words signal and graceful hard to take in the same sentence.

If you read my previous post, you'll see that I agree with that.

To clarify the first part : It's usually not easy to get the signal handler working properly (except for small applications), but if you get it right, then it's ok ...
0
 
billtouchCommented:
i saw that - but had to throw in my 2 cents.... I honestly can't imagine using signals except for emergency stuff like shutting down systems or forcing restarts of specific software.

Bill
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 5
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now