Opened 7 years ago

Closed 7 years ago

#876 closed defect (fixed)

RNG::instance is not thread safe

Reported by: Peter Owned by: Jari Häkkinen
Priority: major Milestone: yat 0.14
Component: random Version: trunk
Keywords: Cc:

Description

This is actually the same as pointed out in ticket #568, but the initial problem was lost along the road there when implementing an RNG that handles multiple threads.

The problem is

RNG* RNG::instance(void)
{
  if (instance_==NULL)
    instance_ = new RNG;
  return instance_;
}

The Double-Checked Locking Pattern is the usual pattern to solve this problem, but as discussed in this paper by Meyers & Alexandrescu there are some problems with that pattern

Thoughts?

Change History (6)

comment:1 Changed 7 years ago by Peter

Here is a talk by Herb Sutter. In modern C++ the problem described by M&A can be solved by using atomic. Since atomic is a c++11 feature we'd need a similar thing in boost or upgrade to c++11 (hmm). Or we can just leave it without atomic; since RNG constructor might throw the problem is minimal to occur.

comment:2 Changed 7 years ago by Peter

atomic exists in boost. It was introduced in version 1.53. I'm fine with an upgrade to 1.53 (1.53 happen to be the version I have installed on my devel machine).

Last edited 7 years ago by Peter (previous) (diff)

comment:3 Changed 7 years ago by Peter

I tried to implement The Double-Checked Locking Pattern but having a mutex in a static function makes probably no sense, the compiler at least thought so.

In file included from yat/random/random.cc:25:0:
yat/random/random.h: In static member function 'static theplu::yat::random::RNG* theplu::yat::random::RNG::instance()':
yat/random/random.h:201:24: error: invalid use of member 'theplu::yat::random::RNG::mutex_' in static member function
   mutable boost::mutex mutex_;

Why is the function static? is that a good thing? what does that error message mean?

comment:4 Changed 7 years ago by Peter

Here is DCLP as I tried it:

	RNG* RNG::instance(void)
	{
		if (instance_==NULL) {
			boost::unique_lock<boost::mutex> lock(mutex_);
			if (instance_==NULL)
				instance_ = new RNG;
		}
		return instance_;
	}

comment:5 Changed 7 years ago by Peter

(In [3567]) refs #876

Implementing The Double-Checked Locking Pattern but without the atomicity to be 100% thread-safe.

comment:6 Changed 7 years ago by Peter

Resolution: fixed
Status: newclosed

atomic is left for the future (see ticket #877)

Note: See TracTickets for help on using tickets.