actionlib goalhandle.cancel() blocking function?

asked 2015-08-06 02:10:45 -0500

kluessi gravatar image

Hi,

its quite some time, but I have a question related to the question
http://answers.ros.org/question/13062...
asked some time ago.

It is maybe related to
http://answers.ros.org/question/52842...

The implementation using the goal handles on client and server side works quite well for using multiple goals.

I have a problem when canceling the goals. On the client side I use a for-loop iterating over the available goal handles (see below). For now, I cancel all goals, but later I just want to cancel a subset of the available goal handles.

When I am doing this the for loop stops at the execution of the cancel() function.

For my understanding this is threading problem. When the GoalHandle.cancel() function is executed. It executes the preemptCallback on the serve side, which will call the transistionCallback on the client side.

I came to the conclusion that the GoalHandle.cancel() function is blocking until the server has finished the preemptCallback and the transistionCallback on the client side. Due to the usage of the goalsMutex in my code on the client side the transistionCallback can't be executed, so my programm hangs in a deadlock.

I just want to know, why the GoalHandle.cancel() function is blocking. Shouldn't it be a non blocking funtion?

Like the ActionClient.cancelAllGoals() function, which is a non blocking function.

But when I use the ActionClient.cancelAllGoals() I can't tell on the server side that all goals shall be canceled, because I just receive one goal handle. Is there an option to detect on the server side if ActionClient.cancelAllGoals() has been called?

Thanks for your help.


Canceling the goal handles on the client side:

boost::unique_lock<boost::mutex> lock(goalsMutex);
int size = goalHandles.size();
for (unsigned int i = 0; i < size; ++i)
{

    std::cout << "C1" << std::endl;
    goalHandles[i].cancel();
    std::cout << "C2" << std::endl;
    goalHandles[i].reset();
    std::cout << "C3" << std::endl;
    goalHandles.erase(i);
}
lock.unlock();

Server Side PreemptCallback:

void ActionServer::preemptCallback(actionServer::GoalHandle &gh)
{
   gh.setCanceled();
}

The Transistion Callback:

void transistionCallback(actionClient::GoalHandle &gh)
{
  boost::unique_lock<boost::mutex> lock(goalsMutex);

  ... do some stuff

   lock.unlock();
}
edit retag flag offensive close merge delete