Boost logo

Boost Users :

Subject: Re: [Boost-users] Passing reference to boost::bind object
From: david.weber_at_[hidden]
Date: 2009-04-08 18:32:44


Ok, found it. Now, the rub.

We have plugins, which register interest in things. When they call a
base-class register() function to register interest, they pass in the
slot that they want the thing's signal to be connected to.

So, the plugin base class (who we want to inherit from
boost:;signals::trackable) keeps a map of interested thing to (formerly
a boost::function) object. When changed to a signal_t::slot_type,
compilation dies.

Looking at slot.hpp, it looks like a slot does not have a copy
constructor, nor an assignment operator. This means we can't store the
slot in an STL container, nor can we pass a boost::function through the
register() function without breaking trackable. Note: The functions are
bound to class instance member functions, so we're using boost::bind.

We were hitting an issue, where the connections weren't being torn down
when the plugin unloads, causing a segfault when the signal was emitted.
Trackable seemed like the easiest mechanism to add this functionality.

So, can we delay turning the bind into a slot somehow? What does bind
actually return? It would seem that if I can store that *bound* object,
and just wait until we need to call connect, we should be fine.

------------------------------------

Just re-read the above, I'll write some pseudo-code to illustrate our
problem

-------------------------------------

Class plugin_base : boost::signals::trackable
{
Public:
        Plugin_base(){};

        // We need to make sure that we tear down our connections...
        ~plugin_base(){};

        Register(int id, boost::function slot)
        {
                registerMap[id] = slot;
        }

        Connect(object obj) // connect obj's signal to plugin_concrete's
slot
        {
                // Prefer not to keep list of connections here.
                // Automate via trackable is preferred.
                Obj.sig.connect(registerMap[obj.id]);
        }

Private:
        Std::map <int, boost::function > registerMap;
}

// I live in a shared library.
// If I am unloaded while still connected to object, we go boom
// when obj.sig() is called.
Class plugin_concrete : plugin_base
{
        Plugin_concrete()
        {
                Register(SOME_ID,
boost::bind(&plugin_concrete::some_slot, this));
        }

        Void some_slot(){};
}

Class object
{
Public:
        Boost::signals::signal< void (void) > sig;
        Int id;
}

---------------------------------------------------

Thanks

--dw


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