如果日期在2116年,则提升timed_wait不会等待

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

本文关键字:timed wait 等待 日期 2116年 如果      更新时间:2023-10-16

示例:

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);

它当时在Linux上工作得很好- timed_wait等待10秒然后返回false

但是,如果我将系统日期移动到2116 year并重新运行应用程序,timed_wait调用立即返回false。boost的条件变量也有同样的问题。

谁能解释一下有什么问题吗?

信息:

  • Linux sles12 3.12.39 x86_64 GNU/Linux
  • g + + 4.8
  • 增加1.54
如前所述,我在64位平台上运行测试,time_t的大小等于8。因此,建议使用64位time_t而不是32位的答案不适用于问题。

让我试着用一个小的堆栈跟踪来描述发生问题的行(顺便说一句,我使用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

好,让我们看看在方法ptime_to_timespec中发生了什么。您之前创建的ptime对象(第3行)

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

被传递给这个函数,并被转换成一个timespec对象。timespec对象在time.h中定义,可用于计算从1970年1月1日00:00:00开始的持续时间。(参见http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html)它包含像tv_sec(持续时间以秒为单位,类型为time_t), tv_nsec(类型为long)等成员。

问题很简单,以秒为单位的持续时间(从01/01/1970开始,以XX/XX/2116结束)太大,不适合tv_sec (time_t基本上是有符号整型)。这里也描述了这个问题:https://stackoverflow.com/a/471287/5967798

我用年份2116和函数返回的描述日期的timespec对它进行了测试9:18:59 am CET | Wednesday, October 8, 1980

问题的根本原因是boost::posix_time::time_duration::total_seconds()显式地将返回值转换为time_resolution_traits::sec_type,而在timed_wait()调用期间通过boost::interprocess::ipcdetail::ptime_to_timespec()ptime转换为timespectime_resolution_traits::sec_type是对 int32_t 类型的类型定义(参见boost/date_time/time_resolution_files .hpp文件中的类型定义链)。

同时文档说time_duration::total_seconds()返回 long (http://www.boost.org/doc/libs/1_62_0/doc/html/date_time/posix_time.html)。但是对于LP64模型(例如Linux, 64位),它返回有符号32位整数,而不是long(有符号64位整数)。

所以很明显在boost中有一个bug。该漏洞的第一张罚单出现在2009年。

门票:

    https://svn.boost.org/trac/boost/ticket/2819
  • https://svn.boost.org/trac/boost/ticket/3109
  • https://svn.boost.org/trac/boost/ticket/3487
  • https://svn.boost.org/trac/boost/ticket/12214
  • 我创建了一个新的:https://svn.boost.org/trac/boost/ticket/12609.


UPD:在Boost 1.66中修复了错误,在错误的注释中描述。