[phobos] Typo (bug) in std.concurrency

Michel Fortin michel.fortin at michelf.com
Fri Jul 2 13:31:58 PDT 2010


Wouldn't it be better to just redefine pthread_mutex_t to always be a shared type? Something like:

	struct pthread_mutex {...}
	alias shared(pthread_mutex) pthread_mutex_t;

or perhaps:

	shared struct phtread_mutex_t {...}


Le 2010-07-02 à 14:50, Andrei Alexandrescu a écrit :

> I think we should bite the bullet and mark the signatures as shared.
> 
> Andrei
> 
> Sean Kelly wrote:
>> As I'd feared, this is getting more and more complicated.  I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors:
>> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> While technically correct, I find this behavior quite frustrating.  I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either.  The simplest alternative fix I've found so far is basically what I described below:
>> class Mutex
>> {
>>    shared void lock()
>>    {
>>        (cast(Mutex) this).doLock();
>>    }
>>    private void doLock()
>>    {
>>        // lock the mutex
>>    }
>> }
>> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing."
>> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this.
>> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote:
>>> Okay, alternate evil solution:
>>> 
>>> class Condition
>>> {
>>>   shared void notify()
>>>   {
>>>       static void doNotify() {}
>>>       (cast(Condition) this).doNotify();
>>>   }
>>> }
>>> 
>>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc).  I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>> 
>>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>> 
>>>> Well that was a disaster.  I have this:
>>>> 
>>>> class MessageBox
>>>> {
>>>>  this()
>>>>  {
>>>>      // this makes m_lock the monitor for the MessageBox instance.
>>>>      m_lock = new Mutex( this );
>>>>      m_cond = new Condition( m_lock );
>>>>  }
>>>> 
>>>>  final synchronized void put( Message msg )
>>>>  {
>>>>      // m_lock is locked now
>>>>      m_list.add( msg );
>>>>      m_cond.notify(); // error: notify () is not callable using argument types () shared
>>>>  }
>>>> }
>>>> 
>>>> struct Tid
>>>> {
>>>>  shared MessageBox mbox;
>>>> }
>>>> 
>>>> class Condition
>>>> {
>>>>  void notify()
>>>>  {
>>>>      // fancy stuff involving semaphores
>>>>  }
>>>> }
>>>> 
>>>> How do I fix this?  Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless.  Should I change the call to notify() to:
>>>> 
>>>> (cast(Condition)m_cond).notify();
>>>> 
>>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox.  If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it.  This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/





More information about the phobos mailing list