Boost logo

Boost Users :

From: Terry G (tjgolubi_at_[hidden])
Date: 2006-11-11 14:49:21


Hello again everyone!
Boo ST == (Scarey signals & threads)

Signals/slots are just too good not to use in a multi-threaded environment.
Someday, this will be fixed, I know. But for now...

I'm trying to serialize access to boost.signals using Bjarne Stroustrups
"wrapper" concept.
Here's what I'm doing. Is this likely to cause problems? Sorry about the
length.
If this is too dangerous, what's a better alternative?

I typed this from memory and didn't try to compile.
Please disregard any typos or syntactic blunders.

// Implements Bjarne Stroustrup's "wrapper" concept using boost::shared_ptr.
template <typename T> class Wrapper {
  T* p;
public:
   explicit Wrapper(T& obj) : p(&obj) { }
   boost::shared_ptr<T> get() const {
      p->prefix();
      return boost::shared_ptr<T>(p, boost::mem_fn(&T::suffix));
   } // get
   boost::shared_ptr<T> operator->() const { return get(); }
}; //Wrapper

// Provides signals through "safe" wrapper. (?)
class TiePoint {
public:
  class Events {
    Mutex lock; // Provided elsewhere.
    void prefix() { lock.acquire(); }
    void suffix() { lock.release(); }
    friend class Wrapper<Events>;
  public:
    boost::signal<void (Signal1Args)> signal1;
    boost::signal<void (Signal2Args)> signal2;
    // etc...
    template <class Iter>
    void disconnect(Iter begin_, Iter end_) {
      std::for_each(begin_, end_,
         boost::mem_fn(&boost::signals::connection::disconnect);
    } // disconnect
  }; // Events
private:
  Events _events;
public:
  Wrapper<Events> events;
  TiePoint() : _events(), event(_events) { }
}; // TiePoint

// Demonstrates use of TiePoint class.
class UsesSignals {
private:
  void handle1(Signal1Args) { ... }
  void handle2(Signal2Args) { ... }
  std::vector<boost::signals::connection> conns; // Be very careful with
these.
public:
  void connect(TiePoint& tiePt) {
    boost::shared_ptr<TiePoint::Events> events = tiePt.events.get();
    conns.push_back(events->signal1.connect(Handle1));
    conns.push_back(events->signal2.connect(Handle2));
  } // connect
  void disconnect(TiePoint& tiePt) {
    tiePt.events->disconnect(conns.begin(), conns.end());
    conns.clear();
  } // disconnect
  void signalJustOne(TiePoint& tiePt) {
    tiePt.events->signal1(signal1args);
  } // signalJustOne
  void signalMany(TiePt& tiePt) {
    boost::shared_ptr<MyClass::Events> events = tiePt.events.get();
    events->signal1(signal1args);
    events->signal2(signal2args);
    ...
  } // signalMany
}; // UsesSignals


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net