digitalmars.D.learn - m_condition.mutex cannot be used in shared method ?
- Marco Leise (17/17) Oct 19 2014 I have a thread that is shared by
- Sean Kelly (17/32) Oct 19 2014 What really needs to happen is for everything in core.sync to be
- Marco Leise (18/36) Oct 20 2014 Thank you for that honest response. The situation is really
- Sean Kelly (23/38) Oct 20 2014 See above. Though there are other problems that will probably
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (5/10) Oct 21 2014 But this change of ownership is usually only temporary:
I have a thread that is shared by others, so I have a shared method, inside of which I wrote: final void opOpAssign(string op : "~")(ref StreamingObject item) shared { synchronized (m_condition.mutex) { m_list.unshared ~= item; m_condition.notify(); } } Error: non-shared method core.sync.condition.Condition.mutex is not callable using a shared object Where exactly should my stuff stop to be shared so I can call .mutex ? Btw.: StreamingObject is a struct unshared is a property that casts away sharedness -- Marco
Oct 19 2014
On Sunday, 19 October 2014 at 13:42:05 UTC, Marco Leise wrote:I have a thread that is shared by others, so I have a shared method, inside of which I wrote: final void opOpAssign(string op : "~")(ref StreamingObject item) shared { synchronized (m_condition.mutex) { m_list.unshared ~= item; m_condition.notify(); } } Error: non-shared method core.sync.condition.Condition.mutex is not callable using a shared object Where exactly should my stuff stop to be shared so I can call .mutex ?What really needs to happen is for everything in core.sync to be made shared. I got partway through this at one point and stopped, because it was imposing a terrible design on the classes--I had shared methods that were casting away shared and then calling the non-shared methods to do the work. The reason for this was that the transitivity of shared was preventing me from calling pthread_mutex_lock or whatever because those functions didn't take a shared pthread_mutex_t. And attempting to rewrite core.sys.posix to make the logically shared types explicitly shared had a cascading effect that made me uncomfortable. Because of this, I remain unconvinced that the semantics of the shared attribute are actually correct when applied to user-defined types. I want some kind of an "I know what I'm doing" label, perhaps equivalent to the "mutable" attribute in C++, but to exempt contained types from shared.
Oct 19 2014
Am Sun, 19 Oct 2014 17:09:22 +0000 schrieb "Sean Kelly" <sean invisibleduck.org>:What really needs to happen is for everything in core.sync to be made shared. I got partway through this at one point and stopped, because it was imposing a terrible design on the classes--I had shared methods that were casting away shared and then calling the non-shared methods to do the work. The reason for this was that the transitivity of shared was preventing me from calling pthread_mutex_lock or whatever because those functions didn't take a shared pthread_mutex_t. And attempting to rewrite core.sys.posix to make the logically shared types explicitly shared had a cascading effect that made me uncomfortable. Because of this, I remain unconvinced that the semantics of the shared attribute are actually correct when applied to user-defined types. I want some kind of an "I know what I'm doing" label, perhaps equivalent to the "mutable" attribute in C++, but to exempt contained types from shared.Thank you for that honest response. The situation is really bizarre. I just tried to create a shared worker thread and there is no ctor in Thread that creates a shared instance. Is a shared constructor even meaningful? [1] If yes, what do we need it for? Can't we otherwise just implicitly and safely cast to shared _after_ the constructor ran when we write `new shared(Foo)(...)`? Casting away shared is not safe. Since this is normal to do in synchronized blocks, I figure the whole core.Thread and core.sync.xxx family are system functionality ? [1] (Note that I created a PR for DMD that disables shared destruction: https://github.com/D-Programming-Language/dmd/pull/4072) -- Marco
Oct 20 2014
On Monday, 20 October 2014 at 09:53:23 UTC, Marco Leise wrote:Thank you for that honest response. The situation is really bizarre. I just tried to create a shared worker thread and there is no ctor in Thread that creates a shared instance. Is a shared constructor even meaningful? [1]If we want to try for having thread-local memory pools then yes.If yes, what do we need it for?See above. Though there are other problems that will probably prevent this anyway (immutable being implicitly shared, for one).Can't we otherwise just implicitly and safely cast to shared _after_ the constructor ran when we write `new shared(Foo)(...)`?Yep.Casting away shared is not safe. Since this is normal to do in synchronized blocks, I figure the whole core.Thread and core.sync.xxx family are system functionality ?Yes. Though I really don't like feeling that casts are necessary in general. If I have to cast in order to do normal work then there's probably something wrong with the type system. Though I'll note that I also use "mutable" in C++ for what I feel are completely justifiable reasons (like on a contained Mutex so I can lock/unlock some region of code in a const method), and D has been firmly established in opposition to logical const. Mutexes are actually a special case in D because they bypass normal type checking thanks to the way synchronized blocks work, and I'm sure we could do something similar for shared, but it feels wrong. I kind of hope that someone will show me that casting away shared isn't necessary, kind of like how Monads are a clever response to immutability in Haskell.[1] (Note that I created a PR for DMD that disables shared destruction: https://github.com/D-Programming-Language/dmd/pull/4072)With all the recent work on the GC, we really really need to start tracking which thread owns a given non-shared object so it can be finalized properly. This may mean having the process of casting away shared make the executing thread the new owner of the object.
Oct 20 2014
On Monday, 20 October 2014 at 17:37:22 UTC, Sean Kelly wrote:With all the recent work on the GC, we really really need to start tracking which thread owns a given non-shared object so it can be finalized properly. This may mean having the process of casting away shared make the executing thread the new owner of the object.But this change of ownership is usually only temporary: with(cast(BaseType) sharedVar) { // ... }
Oct 21 2014