Skip to content
Advertisement

boost timed_wait doesn’t wait if date is in 2116 year

The example:

boost::interprocess::interprocess_semaphore semDone(0);
long sec = 10;
boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(sec);
bool ret = semDone.timed_wait(until);

It works perfectly on Linux at the time – the timed_wait waits for 10 seconds and then returns false.

However if I move the system date to 2116 year and re-run the app, the timed_wait call returns false immediately. There is the same problem with the boost’s condition vars.

Could please anybody explain what’s wrong with it?

Info:

  • Linux sles12 3.12.39 x86_64 GNU/Linux
  • g++ 4.8
  • boost 1.54

UPD As I already wrote above, I’m running the test on 64bit platform, and the size of time_t equals 8. So the answers advising to use 64bit time_t instead of 32bit are not applicable for the question.

Advertisement

Answer

The root cause of the problem is that boost::posix_time::time_duration::total_seconds() explicitly casts the return value to time_resolution_traits::sec_type while converting ptime to timespec via boost::interprocess::ipcdetail::ptime_to_timespec() during the timed_wait() call. The time_resolution_traits::sec_type is a typedef to int32_t type (see the typedef chain in boost/date_time/time_resolution_traits.hpp file).

At the same time documentation says that time_duration::total_seconds() returns long (http://www.boost.org/doc/libs/1_62_0/doc/html/date_time/posix_time.html). But for LP64 models (e.g. Linux, 64bit) it returns signed 32bit integer, not long (signed 64bit integer).

So obviously there is a bug in boost. The first ticket for the bug was created in 2009. And it is still not fixed.

The tickets:


UPD: The bug was fixed in Boost 1.66 as it’s described at the bug’s comments.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement