Opened 9 years ago

Closed 9 years ago

#8768 closed Bugs (fixed)

win32 condition_variable::wait_until infinite wait in rare cases

Reported by: Dmitry Lysachenko <xdemonx07@…> Owned by: viboes
Milestone: Boost 1.55.0 Component: thread
Version: Boost 1.54.0 Severity: Problem
Keywords: win32, thread, condition_variable, wait_until Cc:

Description

on win32 platform condition_variable::wait_until(lk, t) can wait infinite long if

ceil<milliseconds>(t - t::clock::now()).count() == -1

do_wait takes boost::detail::timeout. It constructs from -1 => boost::detail::timeout::milliseconds == 0xf..ff, witch is a special value checked by is_sentinel().

Later in win32/thread.cpp: this_thread::interruptible_wait code waits boost::detail::timeout::max_non_infinite_wait.

tested it with msvs 2010.

attached example

Attachments (1)

wait_until-example.cpp (1.5 KB ) - added by Dmitry Lysachenko <xdemonx07@…> 9 years ago.
repro example

Download all attachments as: .zip

Change History (8)

by Dmitry Lysachenko <xdemonx07@…>, 9 years ago

Attachment: wait_until-example.cpp added

repro example

comment:1 by viboes, 9 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:2 by viboes, 9 years ago

Resolution: wontfix
Status: assignedclosed

The example is to rare to take care of it.

comment:3 by szakharchenko@…, 9 years ago

This isn't at all rare, for example, it's the final cause of my problems in #8323 (the current ticket's author just made it easier to reproduce, and his analysis is more correct than mine). That is, code hitting this problem from time to time can easily be written, and it is extremely hard to find the problem, unless you know that such waits can turn out to be infinite.

comment:4 by s.heil@…, 9 years ago

We ran into this problem as well and after a lot of debugging, we found this ticket. In our case we got bit by that problem in production code, so we really hope it will get fixed. We also have a simple test, that in about 7 of 10 runs reproduces the problem:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>

using namespace std;

int main( int argc, const char* argv[] )
{
	boost::mutex mutex;
	boost::condition_variable variable;
	boost::unique_lock<boost::mutex> lock( mutex );
	for ( int i = 5; i >= - 10; i -- ) {
		boost::chrono::time_point<boost::chrono::steady_clock> time =
			boost::chrono::steady_clock::now() + boost::chrono::milliseconds( i );
		std::cerr << "test " << i << ": " << " ... ";
		variable.wait_until( lock, time );
		std::cerr << "ok" << std::endl;
	}
}

The only solution we see right now is to not ever use wait_until, as it might block forever. So we are replacing all calls to wait_until in our code with calls to wait_for.

comment:5 by viboes, 9 years ago

Resolution: wontfix
Status: closedreopened

Hi,

I think that #9079 includes two examples that are realistic and that seems to have the same issue.

I will try to fix it soon.

comment:6 by viboes, 9 years ago

Milestone: To Be DeterminedBoost 1.55.0

Please, could you try after updating with the following

Changeset [85591],[85592]

Thread: protect condition_variable/_any wait_for and wait_until from …

comment:7 by viboes, 9 years ago

Resolution: fixed
Status: reopenedclosed

Committed revision [85663].

Note: See TracTickets for help on using tickets.