Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

linux

boost

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.

like image 842
Rom098 Avatar asked Dec 29 '25 08:12

Rom098


1 Answers

Let me try to describe what happens with a small stacktrace to the line where the problem occurs (btw, I am using boost 1.58):

#0  boost::interprocess::ipcdetail::ptime_to_timespec (tm=...) at /usr/include/boost/interprocess/sync/posix/ptime_to_timespec.hpp:38
#1  0x402983 in boost::interprocess::ipcdetail::semaphore_timed_wait (handle=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp:224
#2  0x402ab7 in boost::interprocess::ipcdetail::posix_semaphore::timed_wait (this=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/posix/semaphore.hpp:55
#3  0x402b1d in boost::interprocess::interprocess_semaphore::timed_wait (this=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/interprocess_semaphore.hpp:139
#4  0x40184d in main () at /tmp/t.cpp:10

Ok, so lets have a look what happens in the method ptime_to_timespec. Your previously created ptime object (line 3)

boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(sec);

is passed to this function and is converted into a timespec object. The timespec object is defined in time.h and can be used to compute the duration since 00:00:00 January 1, 1970. (see http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html) It contains members like tv_sec (duration in seconds, type time_t), tv_nsec (type long), etc.

The problem simply is that the duration in seconds (starting at 01/01/1970 and ending at XX/XX/2116) is too large and does not fit into tv_sec (time_t is basically a signed int). The problem is also described here: https://stackoverflow.com/a/471287/5967798

I tested it with year 2116 and the timespec that was returned by the function described the date 9:18:59 am CET | Wednesday, October 8, 1980

like image 77
Stefan Moosbrugger Avatar answered Dec 31 '25 00:12

Stefan Moosbrugger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!