Denis Koroskin wrote:
On Wed, 28 Oct 2009 13:17:43 +0300, Walter Bright
<newshou...@digitalmars.com> wrote:
Denis Koroskin wrote:
I've recently updated to DMD2.035 (from DMD2.031 because all the
later versions had issues with imports) and for the first time faced
problems with shared modifier.
I don't need shared and all my globals are __gshared (they are
globally unique instances that don't need per-thread copies).
I don't understand. Are you running multiple threads? Are those
threads accessing globals?
Yes.
A function that accesses shared data has to put in fences. There's no
way to have the same code deal with shared and unshared code.
That's frustrating. I'd like to use the same class for both cases.
But I wonder about code that both uses global variables shared across
threads that don't need synchronization?
You missed the point. I do the synchronization myself and I'm fine with
switching to shared (I do believe it is a nice concept). The reason I
use __gshared is because shared object were garbage-collected while
still being in use a few versions of DMD back and I had no choice but to
switch to __gshared. I hope it is fixed by now.
Which OS are you using? This is definitely a bug. If it's still there,
you can work around by adding the tls data as a "root" to the gc.
But I still can't make my data shared, since shared is transitive
(viral). After a few hours or work I still can't even compile my code.
As an escape from the type system, you can always cast away the
shared-ness.
That's the only way I have now. Casts from shared to unshared *everywhere*:
class BuildManager : BuildListener
{
synchronized void build(shared Target target)
{
// ...
_buildingThread = new shared(Thread)(&_startBuild); // creating
a new shared Thread. Yes, shared Thread, because BuildManager is global.
//_buildingThread.start(); // Error: function
core.thread.Thread.start () is not callable using argument types () shared
(cast(Thread)_buildingThread).start(); // works, but ugly, and I
don't have a reason to hijack the type system in this case
// ...
}
}
Andrei would suggest a Shared!(T) template that would wrap an unshared
type and make all methods shared. This would work, but requires full AST
manipulation capabilities (it's clearly not enough to just mark all the
members shared). What should we do until then?
shared(T) should transitively make a new type where it's all shared.