非常にまれな条件ですが、競合状態だと思います。期間を指定したcondition_variable::timed_wait()の実装は、get_system_time()+wait_durationを使用して値をsystem_timeに変換するだけです。get_system_time()が呼び出されてからシステム時間が変更され、計算された待機終了時間が基になるOS呼び出しのティックベースのカウンターに再変換される場合、待機時間は間違っています。
このアイデアをテストするために、Windowsで、次のように1つのスレッドで100ミリ秒ごとに出力を生成する単純なプログラムを作成しました。
for (;;)
{
boost::this_thread::sleep( boost::get_system_time() +
boost::posix_time::milliseconds( 100 ) );
std::cout << "Ping!" << std::endl;
}
別のスレッドは、過去100ミリ秒ごとにシステム時間を1分戻していました(このスレッドは、システム時間への変換を回避するOSレベルの「Sleep()」呼び出しを使用します)。
for ( ;; )
{
Sleep( 100 );
SYSTEMTIME sysTime;
GetSystemTime( &sysTime );
FILETIME fileTime;
SystemTimeToFileTime( &sysTime, /*out*/&fileTime );
ULARGE_INTEGER fileTime64 = (ULARGE_INTEGER(fileTime.dwHighDateTime) << 32) |
fileTime.dwLowDateTime;
fileTime64 -= 10000000 * 60; // one minute in the past
fileTime.dwHighDateTime = (fileTime64>>32) & 0xFFFFFFFF;
fileTime.dwLowDateTime = fileTime64 & 0xFFFFFFFF;
FileTimeToSystemTime( &fileTime, /*out*/&sysTime );
SetSystemTime( &sysTime );
}
最初のスレッドは、「Ping!」を出力することになっていますが 100ミリ秒ごとに、かなり速くロックされます。
私が何かを見逃していない限り、Boostはシステム時間への内部変換のこの問題を回避するAPIを提供していないようで、アプリは時計の外部変更に対して脆弱なままです。