Re: Is it safe to use function-static pthread_mutex_t mutex
On Sep 4, 6:34 am, Goran <goran.pu...@gmail.com> wrote:
On Sep 4, 2:03 am, Joshua Maurice <joshuamaur...@gmail.com> wrote:
The simplest solutions are pthread_once or to eager-initialize your
mutex ala
namespace
{ mutex_t& foos_mutex()
{ static mutex_t* m = new mutex_t;
return *m;
}
bool force_mutex_init_before_main = (foos_mutex(), true);
}
void foo()
{ guard_t guard(foos_mutex());
// ...
}
That bool is complicated compared to simply initializing that mutex
eagerly. Do you have a specific rationale for that? That is, why not
simply:
namespace
{
mutex m(whatever); // or equivalent
}
void foo()
{
mutex_lock lock(m);
// Do stuff
}
On Sep 3, 5:03 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
This uses the initialize on demand idiom for the mutex to avoid the
static initialization order fiasco for the mutex.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
pthread mutexes require runtime initialization, a call to
pthread_mutex_init or whatever. In your example, the call to
pthread_mutex_init (or whatever its name is) is done during static
initialization. If some other static initialization calls foo(),
there's a 50-50 chance that it attempts to lock m before m has been
constructed, and then bad things happen.
In my implementation using the "initialize on demand" idiom, aka by
making the mutex a function-local static, it will be safely
constructed on first use (ignoring threding issues for the moment). If
the first call to foo is from another translation unit, then foo will
call foos_mutex, and it will construct the mutex. If the first call to
foos_mutex is from the namespace-scope bool initializer, then the
mutex will be constructed.
The bool guarantees that the mutex will be constructed before main (or
before dlopen returns) (ignoring that allowance mentioned in my first
post about delaying static initialization of a translation unit which
doesn't come up in practice often).
Thus, if your program does not create threads before main, then the
mutex construction happens in a single threaded environment, so
there's no threading issues to worry about, and it works as intended
and correctly.
If your thing is in the static init of a DLL, then as long as your DLL
static init doesn't make nontrivial threads, your mutex will be
constructed before dlopen returns, and thus your mutex will again be
constructed in a single threaded environment, making it all work out
correctly. Once dlopen returns, your mutex exists, and multiple
concurrent calls will behave as expected. (This presumes that dlopen
establishes a correct "happens-before" relationship. I'm almost
certain it must.)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]