Ask Your Question
0

Ctrl +C shutdown for a blocking call

asked 2016-08-24 06:17:57 -0600

ROSfc gravatar image

Hello,

Inside my loop

while(ros::ok())
{
// do blocking recvfrom socket
// receives data from socket
recvfrom(s, _buf, buf_size_, 0, (struct sockaddr *) &si_other, &slen);
...

ros::spinOnce();

}

This code work perfectly and the ROS_INFO shows that is receives data from socket port correctly. NOTE here the incoming data is outside ros node. But when I exit using Ctrl+C. The node does not exit. The result is I have to force shutdown. This causes my port to connected. netstat shows the port is still in use. however rosnode list shows that the node has shutdown. This is likely because the code is stuck at the blocking call recvfrom. Any suggestion to overcome this ?

My question is similar to

http://answers.ros.org/question/31570...

But the suggestion spinOnce didnt help

edit retag flag offensive close merge delete

Comments

1

You probably need to set a timeout on your socket so that it exits from recvfrom when no data is received, and eventually has the opportunity to exit the main loop.

ahendrix gravatar imageahendrix ( 2016-08-24 22:04:14 -0600 )edit

Is that the only way ? or rather the recommended way ?

ROSfc gravatar imageROSfc ( 2016-08-30 02:40:41 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2016-08-30 03:17:08 -0600

gvdhoorn gravatar image

updated 2016-09-02 11:33:52 -0600

Is that the only way ? or rather the recommended way ?

I'd say that is the recommended way, as hanging in a system call is never really nice / robust (unless you use a blocking read on a suitable configured file descriptor as a timing device, or waiting for an event). You could look into SO_RCVTIMEO (see Linux: is there a read or recv from socket with timeout?) on SO).

Another option would be using select(..) or Boost asio, but that would be (slightly) more involved.

I guess I will go with timeout then. I am looking if I could use the SIGINT signal in any way

Well, at least according to this (and others), SIGINT might not make it to recvfrom(..) and friends. Which could be why you are hanging in recvfrom(..) when you ctrl+c the roslaunch session. But I haven't verified this.

edit flag offensive delete link more
0

answered 2016-09-02 08:49:05 -0600

ROSfc gravatar image

Just for closure. There are many ways I realised one can do this. As can be seen from the comments above.

  1. Non blocking socket
  2. Recv timeout
  3. Signal handling

I would not recommend signal handling. Also, Recv timeout you can imagine so many system calls becomes very CPU intensive and considering ROS should be light weight. I chose option 1. Non blocking socket with select() as @gvdhoorn suggested.

@gvdhoorn: If you wish post your answer and I will mark it as correct one

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-08-24 05:20:50 -0600

Seen: 660 times

Last updated: Sep 02 '16