FWIW, I changed std.concurrency to allow Tid to be included in a send() until 
this is sorted out correctly.  Please let me know if there are any remaining 
problems with functionality.

On Jul 2, 2010, at 11:49 AM, 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
> [email protected]
> http://lists.puremagic.com/mailman/listinfo/phobos

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to