[tf2_ros] Fix waitForTransform race condition - #966
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
tfoote
left a comment
There was a problem hiding this comment.
That's quite a narrow window to hit the race condition. Covering both of these with the existing mutex makes sense with the deferred callback invocation.
|
I triggered a run in CI using this repos file: |
asymingt
left a comment
There was a problem hiding this comment.
Thank you for finding and fixing this. I spent a few moments seeing if I could create a more deterministic version of the test, which I couldn't. So, I triggered CI and we'll merge if everything goes green.
@tfoote In theory yes. In the test that I have added I had to set the nr of regressions to tens of thousends for it to eventually happen naturally. Time window is just a few lines of cpp. But for some reason on my robot this happens way more frequently. Something like 3 out 10 times. The exact work flow there is:
Somehow, this recreates the perfect scenario for this specific race condition to happen. I wonder if rmw or executor here is playing a role in prolonging that time window such that the race condition occurs more often. @asymingt I agree, unfortunately the only way to guarantee the race condition would be to put a sleep in buffer.cpp itself to winden the race window. Which is also why I was a bit doubting if this test is actually useful here. I mean sure, it needs to work, but it's not really that effective in hitting the right spot. |
Description
Hi,
I was facing a race condition as following:
waitForTransformto lookup a tfwaitForTransformwould eventually timeout.After taking a deeper look at it I noticed that the problem is that there is a slight delay between
addTransformableRequestand ceating the timer. If the transform becomes available in between, thencbwould get triggered, finds an empty map (since timer is not yet added totimer_to_request_map_) so it incorrectly assumes timeout is occured and returns silently. Which meanswaitForTransformnever resolves and it eventually timeouts.Now my proposal is to basically use
timer_to_request_map_mutex_for both adding thecbas well as adding the timer. This way,cbwould not be triggered in between.Recreating this issue only via testing is a bit difficult, because as you can immagine, the race condition happens only in the time between those few lines. That's why I have made a test to repeat the process 100 times. But again, not really a test if sometimes it may or may not happen. To guarantee reproducing it, then you can edit
buffer.cppby adding a small sleep before creating timer's lock such that the callback is added, requested transform is set and only then timer is added. Then you can see the issue without my fixes.