Boost logo

Boost Users :

Subject: Re: [Boost-users] Signals2 benchmark
From: Joren Heit (jorenheit_at_[hidden])
Date: 2015-02-06 20:11:28


Thanks for the many responses and suggestions. However, I'm not sure if
everything applies to my particular application. If it does, I don't think
I fully understand...

My implementation provides an Emitter class (template), rather than a
signal class. Signals are types which act as template parameters to the
Emitter. For example:

using Event1 = Signal<void()>;
using Event2 = Signal<void(int)>;

Emitter<Event1, Event2> em; // normally, you'd probably derive from this
em.connect<Event1>(someFunction);
em.connect<Event2>(otherFunction);
em.emit<Event1>();
em.emit<Event2>(42);

Each Signal-type has its own corresponding vector of slots defined within
the Emitter. Calling connect/disconnect adds/removes a slot to/from this
vector and calling emit() results in iterating over it and calling all its
slots (this is a read-only operation).

I can see trouble arising when thread 1 is iterating the vector while
thread 2 is modifying it. Would it be an idea to have the emitting thread
1. lock the vector,
2. make a local copy,
3. unlock, and
4. iterate the copy?
This way, the modifying thread only needs to wait for the copy being made
instead of every slot being called and executed. Does that make sense at
all?

Thanks again for all the help. Scott Meyers was right in his lectures about
this being a helpful community! Oh, and if my formatting is screwed up, I'm
truly sorry, but I'm writing this on my phone.

Cheers,
Joren
On Feb 6, 2015 9:34 PM, "Gottlob Frege" <gottlobfrege_at_[hidden]> wrote:

> On Fri, Feb 6, 2015 at 2:23 PM, Niall Douglas <s_sourceforge_at_[hidden]>
> wrote:
> > On 6 Feb 2015 at 13:41, Gottlob Frege wrote:
> >
> >> > The easiest solution would be to store the slot as a shared_ptr, and
> >> > make a copy of it (pin it) each time you call the slot.
> >>
> >> So
> >>
> >> Thread 1: call signal,... copy slot shared_ptr,...
> >> Thread 2: disconnect, clean up resources, set global ptrUsedBySlot =
> >> null (since it is no longer used, right?)
> >> Thread 1: call slot
> >> Thread 1: crash on null ptrUsedBySlot
> >
> > shared_ptr provides some atomic_exchange overloads. You could
> > atomically swap a slot being deleted with an empty but valid slot
> > type which calls nothing.
> >
>
> That would work to track the "winner". But if the disconnect thread
> comes in second, it still needs to wait for the slot thread to finish.
> So you still need a waitable synchronization object of some kind.
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



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