March 28, 2007
Frits van Bommel wrote:
> Lutger wrote:
>> Bill Baxter wrote:
>>>
>>> Sounds nice.  Just curious -- what is it you require from dmd 1.10?
>>
>> dmd 1.10 provides std.gc.capacity, which can tell you if a block of memory is allocated by the gc. I use this to check if a delegates comes from an object (with the .ptr property), in which case the signals hooks a delegate with notifyRegister on the object which is called on destruction for auto disconnection.
>> I should have documented this btw.
> 
> You realize that just because a block of memory is GC-allocated doesn't mean it's an Object? It could just as well be a struct, int, dynamic array data or whatever.

Yes of course. This block comes from the .ptr property of a delegate which is already type checked, so there are just a few types left which are unsafe to connect. That's why I said I should have documented it, kinda stupid to leave this important information out...
March 29, 2007
Lutger wrote:
> Dejan Lekic wrote:
>> Lutger, my suggestion is to do what QT does - http://doc.trolltech.com/4.2/threads.html#signals-and-slots-across-threads 
>>
>>
>> Kind regards
>>
>> PS. I would like to see this in Phobos' signal/slot implementation.
> 
> Thank you for the link. It is still not clear to me what is necessary, the QT s/s mechanism is tightly integrated to the whole framework so not seems to be applicable.
> 
> What it comes down to looks like a lot of mutexes to me though. I am not so familiar with multi-threaded programming, perhaps you can help me with these questions:
> 
> Would it be preferable to have a thread safety as an option, and if so in what way? Versioning or seperate classes?
> 
> Do reads from (non-volatile) data need to be synchronized?

I found the answers to my own questions, but upon reflection there seems to be a lot of potential for deadlocks. It will probably take a while for me to figure out the details, I don't want to infest sslot with subtle bugs.
March 29, 2007
Lutger wrote:
> Lutger wrote:
>> Dejan Lekic wrote:
>>> Lutger, my suggestion is to do what QT does - http://doc.trolltech.com/4.2/threads.html#signals-and-slots-across-threads 
>>>
>>>
>>> Kind regards
>>>
>>> PS. I would like to see this in Phobos' signal/slot implementation.
>>
>> Thank you for the link. It is still not clear to me what is necessary, the QT s/s mechanism is tightly integrated to the whole framework so not seems to be applicable.
>>
>> What it comes down to looks like a lot of mutexes to me though. I am not so familiar with multi-threaded programming, perhaps you can help me with these questions:
>>
>> Would it be preferable to have a thread safety as an option, and if so in what way? Versioning or seperate classes?
>>
>> Do reads from (non-volatile) data need to be synchronized?
> 
> I found the answers to my own questions, but upon reflection there seems to be a lot of potential for deadlocks. It will probably take a while for me to figure out the details, I don't want to infest sslot with subtle bugs.

There are a few different approaches available, depending on the guarantees want to provide.  I think Andrei actually wrote an article on this, but I'll be darned if I can find it right now.  One approach would be something like this:

void attach( Slot s )
{
    synchronized
    {
        if( !signaling )
        {
            slots ~= s;
            return;
        }
        queue ~= AddRemove( s, true );
    }
}

void detach( Slot s )
{
    synchronized
    {
        if( !signaling )
        {
            slots.remove( s );
            return;
        }
        queue ~= AddRemove( s, false );
    }
}

void signal()
{
    synchronized
    {
        ++signaling;
    }
    foreach( s; slots )
    {
        s();
    }
    synchronized
    {
        if( signaling == 1 )
        {
            foreach( m; queue )
            {
                if( m.isAdd )
                    slots ~= s;
                else
                    slots.remove( s );
            }
        }
        --signaling;
    }
}

struct AddRemove
{
    Slot slot;
    bool isAdd;
}

The tradeoff here is twofold: first, the signal mechanism must acquire two locks to send a signal, and second, the processing of add/remove requests is asynchronous when a signal is being sent.  Still, it only uses one lock and behavior is fairly predictable.


Sean
March 29, 2007
Sean Kelly wrote:
<snip
> 
> The tradeoff here is twofold: first, the signal mechanism must acquire two locks to send a signal, and second, the processing of add/remove requests is asynchronous when a signal is being sent.  Still, it only uses one lock and behavior is fairly predictable.
> 
> 
> Sean

Thank you very much! I realized a similar scheme is also necessary for single-threaded code, since removal *may* happen during signalling if the GC is run.

My apologies for this bug. I actually had this solved in some previous implementation but it slipped back in again.


March 30, 2007
Mr. Kelly, this is more/less what I would like to have in std.signals ... Is there any chance Mr. Bright will do this? :)
March 30, 2007
Dejan Lekic wrote:
> Mr. Kelly, this is more/less what I would like to have in std.signals
> ... Is there any chance Mr. Bright will do this? :)

I think you'll have to ask Mr. Bright :-)


Sean
1 2
Next ›   Last »