Hm I hate reasoning about edge-cases... they make life so much harder. Guess I'll have to think about this some more.

My original question was about how to benchmark my own version (fairly) against boost, hence this mailing list. As far as I was concerned, this discussion could have been over after the link to all the benchmarks. I never intended this discussion to be about thread safety. However, I can't stress enough that I'm very thankful for all the help! ;-)

The reason I wrote it in the first place was just for fun I guess. After having used the idiom in Qt, it seemed like a nice challenge. Now that it's almost finished, I'd like te see how it holds up against the big guys. Also, it's just a little different than what I've seen of the others, with what I think is a nice syntax.

Cheers,
Joren

P.S. Is that implementation of your sqrt() available on github? Seems interesting! ;-)

On Feb 7, 2015 7:07 AM, "Gottlob Frege" <gottlobfrege@gmail.com> wrote:
On Fri, Feb 6, 2015 at 8:11 PM, Joren Heit <jorenheit@gmail.com> wrote:
> 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?
>

Yeah, you are on the right track.  Making a copy of data while holding
a lock then processing the copy without the lock is often a good
strategy in threading.
However, in this case...

int * somePtr = nullptr;

void someFunction()
{
    // can somePtr change after the check but before the set?
    if (somePtr)
        *somePtr = 17;
}

void cleanupPtr()
{
    // this looks safe, but compilers and CPUs can reorder this code:
    int * tmp = somePtr;
    somePtr = null;
    delete tmp;
}

void thread1()
{
    em.emit<Event1>();
}

void thread2()
{
    em.remove<Event1>(someFunction);
    // now safe to cleanup (?)
    cleanupPtr();
}

Now lets say the emit and the remove are happening "at the same time", and
- Thread1: emit gets to the lock first, makes a copy, and unlocks
- Thread2: remove comes in, gets the lock, removes someFunction, returns
- Thread1: calls someFunction as part of iterating over copy of list
- Thread1: someFunction checks somePtr, sees it is non-null, great! (?)
- Thread2: after returning from remove, calls cleanupPtr
- Thread1: either writes to deleted memory, or writes to null

Threading is fun!

> 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.

You are actually borderline not (or no longer) talking about boost,
but your own code/implementation. Some might call that questionable
for a boost list.
But threading is fun!

P.S. why write your own - why not use boost? Because of performance?
Was that the original point?
P.P.S. correctness is typically better than performance.  I've written
the world's (second) fastest square-root.  It returns 17.  Not very
accurate, but very fast.

Tony
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users