Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in 1.12.13: rosout node spins rather than blocking and waiting, using 100% CPU #1343

Closed
NickZ opened this issue Mar 5, 2018 · 24 comments

Comments

@NickZ
Copy link

NickZ commented Mar 5, 2018

Introduced in faab4cb. This is a bug in the roscpp client.

In callAvailable() in callback_queue.cpp, if no callback is available, wait_for() (located in boost_161_pthread_condition_variable_fwd.h) is called on the condition variable, and is told to wait for a specified amount of time (usually 0.1 seconds). However, instead of waiting for the specified amount of time, it returns immediately, turning this into a spin wait rather than a blocking wait. This leads to the rosout node chewing up 100% of the CPU core.

@NickZ NickZ changed the title Regression: rosout node spins rather than blocking and waiting, using 100% CPU Regression in 1.12.13: rosout node spins rather than blocking and waiting, using 100% CPU Mar 6, 2018
@NickZ
Copy link
Author

NickZ commented Mar 6, 2018

The issue is that, on linux systems and every other platform with monotonic clock set, wait_for() calls steady_clock.now() to get the system time. "steady_clock" is a monotonic time clock that is a relative clock (usually whenever the system booted up.) However, wait_for() => wait_until() => do_wait_until() ultimately calls pthread_cond_timedwait() with a timeout value based on that relative clock value. pthread_cond_timedwait() only takes in absolute system time values. Thus, it immediately returns with a timeout, since the relative time is guaranteed to be smaller than the system time.

@NickZ
Copy link
Author

NickZ commented Mar 6, 2018

Ok, I've discovered the root cause. It's nasty, nasty compiler/linker behavior. Also, the bug is different across boost versions.

pthread_cond_timedwait() does not normally take monotonic clock values. However, when creating the condition_variable, it can set the condition attributes of the pthread condition to accept Monotonic clock values:
image

However, this never actually gets called.

On systems that have boost <1.61 (tested on Ubuntu 16.04), it's supposed to use the condition_variable defined in boost_161_pthread_condition_variable_fwd.h. However, the constructor for the condition variable as defined in that file does not actually get used, it uses the constructor in the system boost library, which does not call the pthread_cond_init function:

image

This is especially bizarre, since I have observed in debugging that it's using the wait_for() and wait_until() function calls in boost_161_pthread_condition_variable_fwd.h.

On systems that have boost >=1.61 (tested on Ubuntu 18.04), it uses the system boost library. Normally, the pthread condition attribute would be set, since we set BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC in callback_queue.cpp. However, we can see that's not the case:
image
It uses the preprocessor else block instead. This is even more bizarre, since it hits numerous other code blocks that require that preprocessor definition.

I don't know how to fix this, unfortunately, but hopefully someone here knows enough compiler/linker juju to fix it.

@flixr
Copy link
Contributor

flixr commented Mar 6, 2018

However, wait_for() => wait_until() => do_wait_until() ultimately calls pthread_cond_timedwait() with a timeout value based on that relative clock value. pthread_cond_timedwait() only takes in absolute system time values. Thus, it immediately returns with a timeout, since the relative time is guaranteed to be smaller than the system time.

That should not really be possible to happen, wait_for(duration) always basically calls wait_until(current_time + duration) where current_time is either derived from system clock or monotonic clock dependent on the BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC define.

I cannot reproduce this issue, could you please provide some more information?

Tried with latest versions from shadow-fixed (ros-kinetic-roscpp 1.12.13 and so on) and the simple listener from ros-kinetic-roscpp-tutorials and it works fine.

@kjaget
Copy link

kjaget commented Mar 9, 2018

I saw this same issue building roscpp from source just recently. Same symptom - near 100% cpu usage in every node. Reverting to 1.12.12 fixed the problem immediately. I can pull info off my system to help diagnose but I'm not sure what might be useful. It is a Ubuntu 16.04 system which is up to date with apt-get but with not much custom built - let me know what info would be useful.

@NickZ
Copy link
Author

NickZ commented Mar 10, 2018

I did some further testing, and apparently this issue does not occur if you build the entire ros_comm stack from scratch; It only occurs if you either already have the base 1.12.12 system packaging installed and you only build ros_comm and roscpp_core, or if you rebuild only the ros_comm part for a source installation. So, some sort of compiler/linker issue. I have to set up some sort of testing apparatus to track the cause down with more specificity.

@flixr
Copy link
Contributor

flixr commented Mar 10, 2018

Hm.. strange. I still can not reproduce this...
What I tried on Ubuntu 16.04 with the released kinetic packages (1.12.12) as base:

  • create a clean catkin workspace based on /opt/ros/kinetic
  • add ros_comm, roscpp_core and ros_tutorials repos with kinetic-devel branch
  • build only rostime, roscpp and ros_tutorials
  • run any of the talker/listeners from the tutorials

I built the parts to be tested and used the rest from /opt/ros/kinetic

catkin build --no-deps rostime
catkin build --no-deps roscpp
catkin build --no-deps roscpp_tutorials

It still works as expected, regardless if I run the listener from the binaries or the rebuilt tutorials...

@NickZ
Copy link
Author

NickZ commented Mar 12, 2018

Ok, this is what I did to reproduce consistently:

  1. Get a fresh Ubuntu 16.04 image (in either a VM, bare-metal, or a lxc/docker container).
  2. Install the ros-base package (sudo apt-get install ros-kinetic-ros-base)
  3. create a clean catkin workspace based on /opt/ros/kinetic
  4. Populate it with ros_comm, roscpp_core, and ros_tutorials repos on the kinetic-devel branch
  5. Either run catkin_make, or use the build process you describe above, I've reproduced it with both.
  6. source devel/setup.bash, run roscore, observe the cpu in top.

@flixr
Copy link
Contributor

flixr commented Mar 12, 2018

Could it be that this is a problem with catkin_make, as I was using catkin from the catkin_tools package...
Does this problem also occur with catkin_make_isolated?

@NickZ
Copy link
Author

NickZ commented Mar 12, 2018

as I've said, I've done this using both the build process described in your post, just usingcatkin, and with catkin_make. I get the same bug.

It does not occur when I have built the whole ros_comm stack from source, using catkin_make_isolated.

@flixr
Copy link
Contributor

flixr commented Mar 12, 2018

Hm.... I used the install space when testing this... will try again with the devel space.
But this still sounds like basically a known issue with caktin_make to me...

@NickZ
Copy link
Author

NickZ commented Mar 13, 2018

Just for reference, what catkin bugs should I be aware of?

@flixr
Copy link
Contributor

flixr commented Mar 13, 2018

Should have phrased it more precisely: known limitation.
Currently I can't find this anywhere in the catkin docs, but it's nicely summarized here: http://catkin-tools.readthedocs.io/en/latest/migration.html

flixr added a commit to flixr/ros_comm that referenced this issue Mar 14, 2018
when building roscpp while already exists in the system, the wrong include file is used...
so explicity copy that to the devel space
@flixr
Copy link
Contributor

flixr commented Mar 14, 2018

Ok, I can reproduce it with the Dockerfile https://gist.github.com/flixr/77e36cfac037700080efd937148b0f7f

To test this

docker build -t test_ros_comm .
docker run -it test_ros_comm

and observe the high cpu load as you said...

I have no clue why this is happening though.

flixr added a commit to flixr/ros_comm that referenced this issue Mar 14, 2018
@flixr
Copy link
Contributor

flixr commented Mar 14, 2018

It's especially weird because we have over 100 devices running with #1250 without problems.
Although that is still on indigo, I just built a new ros-indigo-roscpp debian package on our CI (based on the ros:indigo-perception image) and installed that updated deb in our systems.

@fujitatomoya
Copy link
Contributor

+1

@fujitatomoya
Copy link
Contributor

core tells us the following link problem, we are not sure the root cause of this yet.

when problem observed, libboost_thread is used as following,
which means no pthread_condattr_setclock is issued before.

#0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:225
#1 0x00007fcbd757ebdd in boost::condition_variable::do_wait_until (this=0x10022e8, m=..., timeout=...) at /usr/include/boost/thread/pthread/condition_variable.hpp:108

when problem is NOT observed,
internal class is used with pthread_condattr_setclock.

#0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:225
#1 0x00007fc1f5da5501 in boost::condition_variable::do_wait_until (this=0x74c2e8, m=..., timeout=...)
at /home/sharedata/Projects/ROS1/src/ros_comm/clients/roscpp/include/boost_161_pthread_condition_variable.h:111

@fujitatomoya
Copy link
Contributor

so far, cannot find root cause.
does anyone have clue for this?

@meyerj
Copy link
Contributor

meyerj commented Nov 3, 2018

I was also affected by this issue after I compiled the kinetic version of roscpp from source and tried to dig deeper based on the previous observations posted here.

My preliminary conclusion is that the approach taken in #1014 and #1250, to backport the boost::condition_variable without changing the same symbol name, is dangerous for the following reasons:

  1. Mixing units where BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is set in one, but not in another, are not supported by Boost: https://svn.boost.org/trac10/ticket/12389
    It is supposed to be a system-wide definitions.

  2. It is assumed that the constructors and member functions of TimerManager and CallbackQueue are only defined in certain compilation units where BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is set. I did not find any other definition than in internal_timer_manager.cpp and callback_queue.cpp, but I might have missed something.

    Unfortunately that is not necessarily the case and there are other possibilities how the two classes can be instantiated. It is only the definition of boost::condition_variable seen by the compilation unit where the constructor of TimerManager or CallbackQueue is defined that decides which implementation of the condition_variable constructor gets called:

    • Obviously any TimerManager<T, D, E> instance other than the one created by initInternalTimerManager() in internal_timer_manager.cpp calls the normal constructor of boost::condition_variable.
    • Even SteadyTimer does not define the macro and therefore instantiates a normal, non-monotonic instance of boost::condition_variable when creating a new global TimerManager<SteadyTime, WallDuration, SteadyTimerEvent> instance in SteadyTimer::Impl::start().
    • Implicitly defined copy- or move-constructors could also trigger a construction of boost::condition_variable in compilation units without BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC. However. this should not be the problem here because boost::condition_variable and boost::mutex are non-copyable and non-movable and so are TimerManager<T,D,E> and CallbackQueue.
  3. Inlining. I assume that's the main issue here. These two classes are not the only ones within roscpp that have boost::condition_variable members. There is also one in RosoutAppender and another in ServiceServerLink. The C++ compiler is not enforced to inline the constructor and other member functions although they are defined in the header. Depending on the compiler, compile flags and optimization level it might decide for external linkage and hence only the symbol exported by the first compilation unit that uses it ends up in the final library and will be used by all other compilation units, too. The same applies even to other libraries linked into the process that also export boost::condition_variable symbols. In other words: It is pure luck which version of the constructor and wait_for member functions gets called and there is no guarantee that they are used consistently, because not all compilation units actually use and export all the member functions.

    If this last assumption is correct, the problem only affects roscpp builds without any optimizations enabled (no CMAKE_BUILD_TYPE defined or Debug mode). Release builds are probably not affected because the calls into the backported boost::condition_variable class are inlined and no symbols are exported.

I think the only valid solution is to change the namespace of the backported condition variable implementation, e.g. to boost_161::condition_variable, to get rid of the link ambiguity. Unfortunately that might break ABI-compatibility because the type of a member variable changes, but because the memory layout stays the same it might work.

I will do further tests and propose a patch in the coming days.

@NickZ
Copy link
Author

NickZ commented Nov 3, 2018

@meyerj excellent, thank you for this

@fujitatomoya
Copy link
Contributor

@meyerj i do agree with the #3 assumption.

@ahoarau
Copy link
Contributor

ahoarau commented Dec 4, 2018

@meyerj did you finally fix this issue ?

@meyerj
Copy link
Contributor

meyerj commented Dec 4, 2018

@meyerj did you finally fix this issue ?

Yes, but my patch broke ROS timers and I did not have time yet to look into it again. But I could open a PR with the current patch, if someone else is interested.

meyerj added a commit to meyerj/ros_comm that referenced this issue Dec 4, 2018
…tion_variable (fix ros#1343)

ros#1014 and ros#1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.
@meyerj
Copy link
Contributor

meyerj commented Dec 4, 2018

Non-working patch pushed to kinetic-devel...meyerj:fix-1343.

@meyerj
Copy link
Contributor

meyerj commented Dec 6, 2018

Proposed patch submitted as #1557.

meyerj added a commit to meyerj/ros_comm that referenced this issue Mar 12, 2019
…tion_variable (fix ros#1343)

ros#1014 and ros#1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.
randoms pushed a commit to BluewhaleRobot/ros_comm that referenced this issue Jul 17, 2019
…tion_variable (fix ros/ros_comm#1343)

ros/ros_comm#1014 and ros/ros_comm#1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.
flixr added a commit to flixr/ros_comm that referenced this issue Jan 12, 2020
* fix-1343-melodic-devel:
  roscpp: replace ROSCPP_BOOST_CONDITION_VARIABLE and ROSCPP_BOOST_CONDITION_VARIABLE_HEADER macros by a typedef in internal_condition_variable.h
  test_rosbag: add target dependency to fix unit test failures in parallel builds
  roscpp: fixed Boost version check in CMakeLists.txt
  add missing ns
  add more explicit namespaces
  fix namespaces
  roscpp: remove specialized implementation of TimerManager<T,D,E>::threadFunc() in steady_timer.cpp
  roscpp: do not use boost_161_condition_variable.h on Windows (untested)
  roscpp: use boost::condition_variable::wait_for() instead of deprecated timed_wait()
  roscpp: fix potential busy-wait loop caused by backported Boost condition_variable (fix ros#1343)
dirk-thomas pushed a commit to meyerj/ros_comm that referenced this issue Feb 5, 2020
…tion_variable (fix ros#1343)

ros#1014 and ros#1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.
meyerj added a commit to meyerj/ros_comm that referenced this issue Jul 31, 2020
…ait spinning (ros#1878)

* roscpp: fix potential busy-wait loop caused by backported Boost condition_variable (fix ros#1343)

ros#1014 and ros#1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.

* roscpp: use boost::condition_variable::wait_for() instead of deprecated timed_wait()

This fixes ROS timers in combination with 2c18b9f. The timer
callbacks were not called because the TimerManager's thread function blocked indefinitely on
boost::condition_variable::timed_wait().

Relative timed_wait() uses the system clock (boost::get_system_time()) unconditionally to
calculate the absolute timestamp for do_wait_until(). If the condition variable has been
initialized with BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC, it compares this timestamp
with the monotonic clock and therefore blocks.

This issue has been reported in https://svn.boost.org/trac10/ticket/12728 and will not be
fixed. The timed_wait interface is apparently deprecated.

* roscpp: do not use boost_161_condition_variable.h on Windows (untested)

* roscpp: remove specialized implementation of TimerManager<T,D,E>::threadFunc() in steady_timer.cpp

The updated generic definition in timer_manager.h should do the same with a minor update.
In all cases we can call boost::condition_variable::wait_until() with an absolute time_point of the respective clock.
The conversion from system_clock to steady_clock for Time and WallTime is done internally in
boost::condition_variable::wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& t).

* fix namespaces

* add more explicit namespaces

* add missing ns

* roscpp: fixed Boost version check in CMakeLists.txt

find_package(Boost) has to come before checking the Boost version.
Otherwise BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC was not defined which
triggered the assertion in timer_manager.h:240.

Since Boost 1.67 BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC became the default
if the platform supports it and the macro is not defined anymore. Instead, check
for BOOST_THREAD_INTERNAL_CLOCK_IS_MONO.

* roscpp: replace ROSCPP_BOOST_CONDITION_VARIABLE and ROSCPP_BOOST_CONDITION_VARIABLE_HEADER macros by a typedef in internal_condition_variable.h

* Remove copy of boost::condition_variable implementation from Boost 1.61 in namespace boost_161

* Revert some changes in include directives and in CMakeLists.txt to minimize the diff to melodic-devel

Addresses ros#1878 (review).

* use wait_for(), remove TimerManagerTraits

* Revert "use wait_for(), remove TimerManagerTraits"

This reverts commit 2a67cf6.

Co-authored-by: Antoine Hoarau <703240+ahoarau@users.noreply.github.com>
Co-authored-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>
dirk-thomas added a commit that referenced this issue Aug 3, 2020
…tonic clock [kinetic-devel] (#2011)

* Drop custom implementation of boost::condition_variable to fix busy-wait spinning (#1878)

* roscpp: fix potential busy-wait loop caused by backported Boost condition_variable (fix #1343)

#1014 and #1250 introduced a backported
version of boost::condition_variable, where support for steady (monotonic) clocks has been added in version 1.61.
But the namespace of the backported version was not changed and the symbol names might clash with the original
version.

Because the underlying clock used for the condition_variable is set in the constructor and must be
consistent with the the expectations within member variables. The compiler might choose to inline one or the
other or both, and is more likely to do so for optimized Release builds. But if it does not, the symbol ends
up in the symbol table of roscpp and depending on which other libraries will be linked into the process it
is unpredictable which of the two versions will be actually called at the end. In case the constructor defined
in `/usr/include/boost/thread/pthread/condition_variable.hpp` was called and did not configure the internal
pthread condition variable for monotonic clock, each call to the backported do_wait_until() method with a
monotonic timestamp will return immediately and hence causes `CallbackQueue::callOne(timeout)` or
`CallbackQueue::callAvailable(timeout)` to return immediately.

This patch changes the namespace of the backported condition_variable implementation to boost_161. This
removes the ambiguity with the original definition if both are used in the same process.

* roscpp: use boost::condition_variable::wait_for() instead of deprecated timed_wait()

This fixes ROS timers in combination with 2c18b9f. The timer
callbacks were not called because the TimerManager's thread function blocked indefinitely on
boost::condition_variable::timed_wait().

Relative timed_wait() uses the system clock (boost::get_system_time()) unconditionally to
calculate the absolute timestamp for do_wait_until(). If the condition variable has been
initialized with BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC, it compares this timestamp
with the monotonic clock and therefore blocks.

This issue has been reported in https://svn.boost.org/trac10/ticket/12728 and will not be
fixed. The timed_wait interface is apparently deprecated.

* roscpp: do not use boost_161_condition_variable.h on Windows (untested)

* roscpp: remove specialized implementation of TimerManager<T,D,E>::threadFunc() in steady_timer.cpp

The updated generic definition in timer_manager.h should do the same with a minor update.
In all cases we can call boost::condition_variable::wait_until() with an absolute time_point of the respective clock.
The conversion from system_clock to steady_clock for Time and WallTime is done internally in
boost::condition_variable::wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& t).

* fix namespaces

* add more explicit namespaces

* add missing ns

* roscpp: fixed Boost version check in CMakeLists.txt

find_package(Boost) has to come before checking the Boost version.
Otherwise BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC was not defined which
triggered the assertion in timer_manager.h:240.

Since Boost 1.67 BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC became the default
if the platform supports it and the macro is not defined anymore. Instead, check
for BOOST_THREAD_INTERNAL_CLOCK_IS_MONO.

* roscpp: replace ROSCPP_BOOST_CONDITION_VARIABLE and ROSCPP_BOOST_CONDITION_VARIABLE_HEADER macros by a typedef in internal_condition_variable.h

* Remove copy of boost::condition_variable implementation from Boost 1.61 in namespace boost_161

* Revert some changes in include directives and in CMakeLists.txt to minimize the diff to melodic-devel

Addresses #1878 (review).

* use wait_for(), remove TimerManagerTraits

* Revert "use wait_for(), remove TimerManagerTraits"

This reverts commit 2a67cf6.

Co-authored-by: Antoine Hoarau <703240+ahoarau@users.noreply.github.com>
Co-authored-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>

* Use an internal implementation of boost::condition_variable with monotonic clock (#1932)

* Use an internal implementation of condition_variable with monotonic clock to avoid ODR violation

* Fix build of ros/internal/condition_variable.h for Boost <1.65

* Fix "static_assert with no message is a C++17 extension" warning in ros/internal/condition_variable.h

* roscpp: fix ros/internal/condition_variable.h for pre-C++11 compilers

Co-authored-by: Antoine Hoarau <703240+ahoarau@users.noreply.github.com>
Co-authored-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants