Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-01-26 07:53:56


John Maddock wrote:
>>Is the behaviour of this in a multiple-threaded environment correct?
>
>
> I was hoping no one would ask that!
>
> The answer is : it depends upon the compiler, but currently most do *not*
> initialise static data in a thread safe manner, I believe that Comeau may be
> an exception to that rule, but I'm not certain about that.
>
> Provided you don't want to call the procedure during program startup, you
> can just make the data a global variable:
>
> static const boost::regex e("\\A\\s+|\\s+\\z");
> std::string trim(const std::string & s)
> {
> return regex_replace(s, e, "");
> }
>
> and then that is thread safe, albeit less elegant.
>
> Otherwise you need to add a mutex that can be statically initialised:
>
> std::string trim(const std::string & s)
> {
> static mutex_type m = STATIC_MUTEX_INITIALISER;
> mutex_type::scoped_lock l(m);
> static const boost::regex e("\\A\\s+|\\s+\\z");
> return regex_replace(s, e, "");
> }
>
> However this uses "too much" locking since we need only lock during object
> construction, there may be better versions available, but they generally
> rely on OS specific features like test and set on a pointer (that's why it
> would be far better for the compiler too handle this).
>
> Such a mutex type does not yet exist in boost, but pthread.h supplies one if
> you're using POSIX threads, and I have a portable (ish) version that I'm
> using for a future regex release, and which may also get submitted to Boost
> at some point.

How about using Boost.Thread's call_once function? I realize it requires
extra code, but something along these lines seems like it should both
avoid too much locking and still work:

#include <boost/thread/once.hpp>

static boost::once_flag once = BOOST_ONCE_INIT;

const boost::regex& get_regex()
{
    static const boost::regex e("\\A\\s+|\\s+\\z");
    return e;
}

void init()
{
    get_regex();
}

std::string trim(const std::string & s)
{
    boost::call_once(&init, once);
    return regex_replace(s, get_regex(), "");
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk