Discussion:
m_condition.mutex cannot be used in shared method ?
Marco Leise via Digitalmars-d-learn
2014-10-19 13:51:49 UTC
Permalink
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
Sean Kelly via Digitalmars-d-learn
2014-10-19 17:09:22 UTC
Permalink
Post by Marco Leise via Digitalmars-d-learn
I have a thread that is shared by
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.
Marco Leise via Digitalmars-d-learn
2014-10-20 10:03:06 UTC
Permalink
Am Sun, 19 Oct 2014 17:09:22 +0000
Post by Sean Kelly via Digitalmars-d-learn
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
Sean Kelly via Digitalmars-d-learn
2014-10-20 17:37:21 UTC
Permalink
Post by Marco Leise via Digitalmars-d-learn
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.
Post by Marco Leise via Digitalmars-d-learn
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).
Post by Marco Leise via Digitalmars-d-learn
Can't we otherwise just implicitly and safely cast to shared
_after_ the constructor ran when we write `new
shared(Foo)(...)`?
Yep.
Post by Marco Leise via Digitalmars-d-learn
do in synchronized blocks, I figure the whole core.Thread and
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.
Post by Marco Leise via Digitalmars-d-learn
[1]
(Note that I created a PR for DMD that disables shared
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.
via Digitalmars-d-learn
2014-10-21 09:40:14 UTC
Permalink
Post by Sean Kelly via Digitalmars-d-learn
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) {
// ...
}

Continue reading on narkive:
Loading...