digitalmars.D - Re: TDPL, shared data, and Phobos
- Sean Kelly <sean invisibleduck.org> Jul 17 2010
- Graham St Jack <graham.stjack internode.on.net> Jul 17 2010
- Sean Kelly <sean invisibleduck.org> Jul 18 2010
- Sean Kelly <sean invisibleduck.org> Jul 18 2010
- Graham St Jack <graham.stjack internode.on.net> Jul 19 2010
- Brian Palmer <d brian.codekitchen.net> Jul 20 2010
- Sean Kelly <sean invisibleduck.org> Jul 22 2010
The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
Jul 17 2010
On Sat, 17 Jul 2010 11:42:03 -0400, Sean Kelly wrote:The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
I'm glad you announced you intention - I was just about to roll up my sleeves and give it a go for Condition, but will wait for the next release. Like all my previous attempts to use shared, I have waited for quite a while for things to improve, tried using shared again, hit a brick wall and resorted to defeating the compiler's detection of shared data. TDPL raised my hopes without actually making it clear how to use synchronized classes. Alas, it seems to me that they still aren't usable in practice. With any luck the problems are just library issues which can be fixed relatively easily. Like Brian Palmer, I am frustrated by the lack of documentation about shared and druntime's sync package, and am happy to lend a hand if that would be helpful. The code I am trying to write is a simple synchronized class with a Condition, but I can't create a Condition on a shared "this". A cut-down version of what I want to write is: synchronized class Foo { Condition mCondition; this() { mCondition = cast(shared) new Condition(this); } void some_method() { } } I realise that Condition wants a Mutex, but a synchronized class already has an implicit one which is implicitly used by all the methods, so the above is definitely what I want to write. What I have to write instead (which avoids the compiler noticing that anything is being shared) is: class Foo { Mutex mMutex; Condition mCondition; this() { mMutex = new Mutex(); mCondition = new Condition(mMutex); } void some_method() { synchronized(mMutex) { } } } The latter works just fine, but it is very disappointing after all the fuss about how important shared is that you can't actually use it for the most mainstream of all uses - a synchronized class with a condition (which is what a message queue between threads is supposed to be).
Jul 17 2010
Graham St Jack <graham.stjack internode.on.net> wrote:On Sat, 17 Jul 2010 11:42:03 -0400, Sean Kelly wrote:The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
I'm glad you announced you intention - I was just about to roll up my sleeves and give it a go for Condition, but will wait for the next release. Like all my previous attempts to use shared, I have waited for quite a while for things to improve, tried using shared again, hit a brick wall and resorted to defeating the compiler's detection of shared data. TDPL raised my hopes without actually making it clear how to use synchronized classes. Alas, it seems to me that they still aren't usable in practice. With any luck the problems are just library issues which can be fixed relatively easily. Like Brian Palmer, I am frustrated by the lack of documentation about shared and druntime's sync package, and am happy to lend a hand if that would be helpful. The code I am trying to write is a simple synchronized class with a Condition, but I can't create a Condition on a shared "this". A cut-down version of what I want to write is: synchronized class Foo { Condition mCondition; this() { mCondition = cast(shared) new Condition(this); } void some_method() { } } I realise that Condition wants a Mutex, but a synchronized class already has an implicit one which is implicitly used by all the methods, so the above is definitely what I want to write. What I have to write instead (which avoids the compiler noticing that anything is being shared) is: class Foo { Mutex mMutex; Condition mCondition; this() { mMutex = new Mutex(); mCondition = new Condition(mMutex); } void some_method() { synchronized(mMutex) { } } } The latter works just fine, but it is very disappointing after all the fuss about how important shared is that you can't actually use it for the most mainstream of all uses - a synchronized class with a condition (which is what a message queue between threads is supposed to be).
new Mutex(this) makes the mutex the object monitor, so it will be what's locked for synchronized functions.
Jul 18 2010
Graham St Jack Wrote:The code I am trying to write is a simple synchronized class with a Condition, but I can't create a Condition on a shared "this". A cut-down version of what I want to write is: synchronized class Foo { Condition mCondition; this() { mCondition = cast(shared) new Condition(this); } void some_method() { } } I realise that Condition wants a Mutex, but a synchronized class already has an implicit one which is implicitly used by all the methods, so the above is definitely what I want to write.
The built-in mutex is created on first use, so what you can do is drop in core.sync.mutex.Mutex before this happens (the library Mutex can be assigned as an object monitor). If 'shared' weren't an issue, the code would be: synchronized class Foo { Condition mCond; Mutex mLock; this() { mLock = new Mutex(this); // make mutex this object's monitor mCond = new Condition(mLock); // bind condition to mLock } void some_method() { // locks mLock mLock.notify(); // safe because mLock is locked } }
Jul 18 2010
On Sun, 18 Jul 2010 16:05:08 +0000, Sean Kelly wrote:Graham St Jack <graham.stjack internode.on.net> wrote:On Sat, 17 Jul 2010 11:42:03 -0400, Sean Kelly wrote:The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
I'm glad you announced you intention - I was just about to roll up my sleeves and give it a go for Condition, but will wait for the next release. Like all my previous attempts to use shared, I have waited for quite a while for things to improve, tried using shared again, hit a brick wall and resorted to defeating the compiler's detection of shared data. TDPL raised my hopes without actually making it clear how to use synchronized classes. Alas, it seems to me that they still aren't usable in practice. With any luck the problems are just library issues which can be fixed relatively easily. Like Brian Palmer, I am frustrated by the lack of documentation about shared and druntime's sync package, and am happy to lend a hand if that would be helpful. The code I am trying to write is a simple synchronized class with a Condition, but I can't create a Condition on a shared "this". A cut-down version of what I want to write is: synchronized class Foo { Condition mCondition; this() { mCondition = cast(shared) new Condition(this); } void some_method() { } } I realise that Condition wants a Mutex, but a synchronized class already has an implicit one which is implicitly used by all the methods, so the above is definitely what I want to write. What I have to write instead (which avoids the compiler noticing that anything is being shared) is: class Foo { Mutex mMutex; Condition mCondition; this() { mMutex = new Mutex(); mCondition = new Condition(mMutex); } void some_method() { synchronized(mMutex) { } } } The latter works just fine, but it is very disappointing after all the fuss about how important shared is that you can't actually use it for the most mainstream of all uses - a synchronized class with a condition (which is what a message queue between threads is supposed to be).
new Mutex(this) makes the mutex the object monitor, so it will be what's locked for synchronized functions.
That's cool. I look forward to shared not being an issue ;-) I assume that when Condition and Mutex are shareable, I will then (from your other post) write: synchronized class Foo { Mutex mMutex; Condition mCondition; this() { mMutex = cast(shared) new Mutex(this); mCondition = cast(shared) new Condition(mMutex); } void some_method() { ... mCondition.notify; // ok because mMutex is locked } }
Jul 19 2010
Thanks Sean, it's great to at least know where the issue is. As to my other question, why do the D std library docs at http://www.digitalmars.com/d/2.0/phobos/phobos.html have no indication that core.sync and the other core.* packages even exist? Are the APIs not stable enough yet to treat them as public? Even if documentation is sparse, just knowing that RWLock existed and its exposed methods was all I really needed to start using it, aside from the shared issue. -- Brian Sean Kelly Wrote:The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
Jul 20 2010
The core stuff is in a different repository, and I haven't done all the work to integrate the docs yet. I sent a file to do most of this to the Phobos list though, if you're inclined to track it down. Brian Palmer <d brian.codekitchen.net> wrote:Thanks Sean, it's great to at least know where the issue is. As to my other question, why do the D std library docs at http://www.digitalmars.com/d/2.0/phobos/phobos.html have no indication that core.sync and the other core.* packages even exist? Are the APIs not stable enough yet to treat them as public? Even if documentation is sparse, just knowing that RWLock existed and its exposed methods was all I really needed to start using it, aside from the shared issue. -- Brian Sean Kelly Wrote:The casts are necessary because I haven't yet applied 'shared' to druntime. I ran into a few issues when doing so and rolled back my changes. I'll give it another shot before the next release.
Jul 22 2010