$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: jsiek_at_[hidden]
Date: 2000-06-05 17:49:51
My main complaint was the complexity of the atomic traits... but
if that is separate from the mutex, and if it can be made a bit
more generic, then I'll be OK with it.
As for the syntax of lock/unlock... well while we're being
cute, how about the following abuse of a for loop?
for (guard g(lock(m)); g; g.release()) {
// critical section
}
This is pretty close to what John proposed... I've just added this
lock() function which solves the accidental default construction
problem, and used the "for" loop to create a convenient place to put
the g.release().
#include <iostream>
#include <boost/utility.hpp>
using namespace std;
struct mutex { };
namespace detail {
struct guard_initializer { };
}
detail::guard_initializer lock(mutex) {
cout << "lock" << endl;
return detail::guard_initializer();
}
struct guard : boost::noncopyable {
guard(detail::guard_initializer) : _locked(true) { }
operator bool() { return _locked; }
void release() {
cout << "unlock via release" << endl;
_locked = false;
}
~guard() {
if (_locked)
cout << "unlock via destructor" << endl;
}
bool _locked;
};
mutex m;
int
main(int,char*[])
{
try {
cout << "before the critical section" << endl;
for (guard g(lock(m)); g; g.release()) {
cout << "in a critical section" << endl;
}
cout << "after first critical section" << endl;
for (guard g(lock(m)); g; g.release()) {
cout << "in another critical section" << endl;
throw "foo";
}
cout << "after second critical section" << endl;
} catch (...) {
cout << "exception caught" << endl;
}
return 0;
}
This output is:
before the critical section
lock
in a critical section
unlock via release
after first critical section
lock
in another critical section
unlock via destructor
exception caught