www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with Mutex

reply "Neven" <neven.miculinic+d gmail.com> writes:
I'm trying to use Mutex from core.sync.mutex; but when I try to 
initialize it at compile time this error pops up:

Error: constructor core.sync.mutex.Mutex.this 
core.sync.mutex.Mutex cannot be constructed at compile time, 
because the constructor has no available source code

So I try to initialize it at run time but whenever I use that 
mutex in code (via synchronized blocks) I get segmetation faults 
(SIGSEGV).

Code here: http://pastebin.com/Z8Yj2kwY
Oct 26 2014
parent reply "Damian" <damianday hotmail.co.uk> writes:
On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
 I'm trying to use Mutex from core.sync.mutex; but when I try to 
 initialize it at compile time this error pops up:

 Error: constructor core.sync.mutex.Mutex.this 
 core.sync.mutex.Mutex cannot be constructed at compile time, 
 because the constructor has no available source code

 So I try to initialize it at run time but whenever I use that 
 mutex in code (via synchronized blocks) I get segmetation 
 faults (SIGSEGV).

 Code here: http://pastebin.com/Z8Yj2kwY
Try __gshared Mutex mutex;
Oct 26 2014
parent reply "Neven" <neven.miculinic+d gmail.com> writes:
On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
 On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
 I'm trying to use Mutex from core.sync.mutex; but when I try 
 to initialize it at compile time this error pops up:

 Error: constructor core.sync.mutex.Mutex.this 
 core.sync.mutex.Mutex cannot be constructed at compile time, 
 because the constructor has no available source code

 So I try to initialize it at run time but whenever I use that 
 mutex in code (via synchronized blocks) I get segmetation 
 faults (SIGSEGV).

 Code here: http://pastebin.com/Z8Yj2kwY
Try __gshared Mutex mutex;
Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?
Oct 26 2014
next sibling parent "Damian" <damianday hotmail.co.uk> writes:
On Sunday, 26 October 2014 at 22:53:09 UTC, Neven wrote:
 On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
 On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
 I'm trying to use Mutex from core.sync.mutex; but when I try 
 to initialize it at compile time this error pops up:

 Error: constructor core.sync.mutex.Mutex.this 
 core.sync.mutex.Mutex cannot be constructed at compile time, 
 because the constructor has no available source code

 So I try to initialize it at run time but whenever I use that 
 mutex in code (via synchronized blocks) I get segmetation 
 faults (SIGSEGV).

 Code here: http://pastebin.com/Z8Yj2kwY
Try __gshared Mutex mutex;
Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?
You can use auto mutex = cast(shared)(new Mutex());
Oct 26 2014
prev sibling next sibling parent reply "Damian" <damianday hotmail.co.uk> writes:
On Sunday, 26 October 2014 at 22:53:09 UTC, Neven wrote:
 On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
 On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
 I'm trying to use Mutex from core.sync.mutex; but when I try 
 to initialize it at compile time this error pops up:

 Error: constructor core.sync.mutex.Mutex.this 
 core.sync.mutex.Mutex cannot be constructed at compile time, 
 because the constructor has no available source code

 So I try to initialize it at run time but whenever I use that 
 mutex in code (via synchronized blocks) I get segmetation 
 faults (SIGSEGV).

 Code here: http://pastebin.com/Z8Yj2kwY
Try __gshared Mutex mutex;
Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?
Globally you can use: Mutex mutex; static this() { mutex = new Mutex(); }
Oct 26 2014
parent reply "Neven" <neven.miculinic+d gmail.com> writes:
 Damian
 You can use auto mutex = cast(shared)(new Mutex());
Not working; Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code
Mutex mutex;
static this()
{
  mutex = new Mutex();
}
I have synchronization problems with this one. Even when I prepend __gshared Mutex mutex in this case. Changed code: http://pastebin.com/KmxCemn3 Output: http://pastebin.com/zFFLnCTD As you can see beginning is not what I expect to get. ketmar
 having thread-locals instead of globals by default can be 
 confusing if
you missed that in documentation. just use 'shared' or '__gshared' to get "real" globals. Thank you for clearing this up. If I understand correctly, __gshared is more of a hack to get C-like global variables, whilst shared is typed shared variable and more preferred?
Oct 26 2014
next sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sun, 26 Oct 2014 23:37:25 +0000
Neven via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

Mutex mutex;
static this()
{
  mutex =3D new Mutex();
}
=20 I have synchronization problems with this one. Even when I=20 prepend __gshared Mutex mutex in this case.
ah, there is another subtle thing. 'static this()' will be called for each new thread, so what you actually doing is creating new mutex object when each thread started. it's the same thing as with globals vs thread-locals. what you really want in this case is 'global initializer', which will be called once on program startup. to achieve this you have to write: shared static this () { mutex =3D new Mutex(); } 'shared static this()' will be called only once.
 Thank you for clearing this up. If I understand correctly,=20
 __gshared is more of a hack to get C-like global variables,=20
 whilst shared is typed shared variable and more preferred?
yes and no. 'shared' is the part of the type, while '__gshared' is not. i.e. shared int a; pragma(msg, typeof(a)); // this will print "shared(int)" __gshared int b; pragma(msg, typeof(b)); // this will print "int" you can't freely mix shared and non-shared types, so you must cast 'shared' away on occasion and cast it back when necessary. this is not safe and error-prone. '__gshared', for the other side, doesn't influence the type, so you can have global variable which can be passed to other functions without casting. but yes, generally this is a hack, and you'd better avoid '__gshared' in idiomatic D code unless you are really really know what you are doing and what consequences it may have. ;-)
Oct 26 2014
prev sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Mon, 27 Oct 2014 02:07:09 +0200
ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 Thank you for clearing this up. If I understand correctly,=20
 __gshared is more of a hack to get C-like global variables,=20
 whilst shared is typed shared variable and more preferred?
yes and no. 'shared' is the part of the type, while '__gshared' is not. i.e. =20 shared int a; pragma(msg, typeof(a)); // this will print "shared(int)" =20 __gshared int b; pragma(msg, typeof(b)); // this will print "int" =20 you can't freely mix shared and non-shared types, so you must cast 'shared' away on occasion and cast it back when necessary. this is not safe and error-prone. =20 '__gshared', for the other side, doesn't influence the type, so you can have global variable which can be passed to other functions without casting. =20 but yes, generally this is a hack, and you'd better avoid '__gshared' in idiomatic D code unless you are really really know what you are doing and what consequences it may have. ;-)
here is some silly code to show you some difference between 'shared' and '__gshared': void foo (ref int i) {} int a; shared int b; __gshared int c; void main () { foo(a); // this compiles foo(b); // this will not compile (see below) foo(c); // this compiles too } `foo(b);` will not compile, compiler emits error: "Error: function y01.foo (ref int i) is not callable using argument types (shared(int))" if you'll change `foo` to `void foo (ref shared int i) {}`, you'll get the opposite: `foo(a)` and `foo(c)` will be refused by compiler.
Oct 26 2014
prev sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sun, 26 Oct 2014 22:53:07 +0000
Neven via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Why cannot I globally have auto mutex =3D new Mutex? And why it=20
 works now when I put __gshared?
this is because 'auto mutex =3D new Mutex' is not a global declaration, it's thread-local declaration. all D variables are thread-locals by default. i.e. you have one indepented Mutex for each thread. and you initialized it only in one thread, all other threads got unitialized Mutex objects. having thread-locals instead of globals by default can be confusing if you missed that in documentation. just use 'shared' or '__gshared' to get "real" globals.
Oct 26 2014
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/26/14 7:13 PM, ketmar via Digitalmars-d-learn wrote:
 On Sun, 26 Oct 2014 22:53:07 +0000
 Neven via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Why cannot I globally have auto mutex = new Mutex? And why it
 works now when I put __gshared?
this is because 'auto mutex = new Mutex' is not a global declaration, it's thread-local declaration. all D variables are thread-locals by default. i.e. you have one indepented Mutex for each thread. and you initialized it only in one thread, all other threads got unitialized Mutex objects. having thread-locals instead of globals by default can be confusing if you missed that in documentation. just use 'shared' or '__gshared' to get "real" globals.
Just as a followup, for some reason Mutex is not callable as a shared object, so you have to make it __gshared. This is unfortunate, but it is the only way to do it right now. Because an actual mutex is thread safe, it is not a problem. -Steve
Oct 27 2014
next sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Mon, 27 Oct 2014 09:24:13 -0400
Steven Schveighoffer via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:

 Just as a followup, for some reason Mutex is not callable as a shared=20
 object, so you have to make it __gshared.
that's due to difference betwen plain type and shared type. `shared(Mutex)` is not the same as simply `Mutex`. to use class as shared var you have to declare it as 'shared class'. or at least declare some of class methods as 'shared'. but for Mutex it's perfectly ok to use it as '__gshared' object.
Oct 27 2014
prev sibling next sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Mon, 27 Oct 2014 09:24:13 -0400
Steven Schveighoffer via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:

 Just as a followup, for some reason Mutex is not callable as a shared=20
 object, so you have to make it __gshared.
=20
 This is unfortunate, but it is the only way to do it right now.
 Because an actual mutex is thread safe, it is not a problem.
p.s. generally you have to write code that can be used with shared vars with special accuracy. that's why D made a clear distinction between shared and thread variables and classes. you must explicitly declare your intention to use something as shared. generally this increases code safety and allows to writte better code. this can be somewhat unusual for those who used to use C/C++ before, as there is no such "guards" though.
Oct 27 2014
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/27/14 9:34 AM, ketmar via Digitalmars-d-learn wrote:
 On Mon, 27 Oct 2014 09:24:13 -0400
 Steven Schveighoffer via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 Just as a followup, for some reason Mutex is not callable as a shared
 object, so you have to make it __gshared.

 This is unfortunate, but it is the only way to do it right now.
 Because an actual mutex is thread safe, it is not a problem.
p.s. generally you have to write code that can be used with shared vars with special accuracy. that's why D made a clear distinction between shared and thread variables and classes. you must explicitly declare your intention to use something as shared. generally this increases code safety and allows to writte better code.
But the result is that you can't use a mutex embedded in a shared object without casting (except for when it's the object's Monitor). Ironically, that's the one place you NEED a mutex. It's not a good situation.
 this can be somewhat unusual for those who used to use C/C++ before, as
 there is no such "guards" though.
The 'shared' system is really underdesigned in D, and needs complete overhaul. The opposite of it (default unshared) is an extremely useful mechanism. -Steve
Oct 27 2014
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, October 27, 2014 09:24:13 Steven Schveighoffer via Digitalmars-d-
learn wrote:
 Just as a followup, for some reason Mutex is not callable as a shared
 object, so you have to make it __gshared.

 This is unfortunate, but it is the only way to do it right now. Because
 an actual mutex is thread safe, it is not a problem.
The reason that it's not shared is because Sean Kelly didn't want to make much of anything in druntime shared until shared was better ironed out, which keeps getting talked about but never done. - Jonathan M Davis
Oct 27 2014
parent "Sean Kelly" <sean invisibleduck.org> writes:
On Monday, 27 October 2014 at 19:13:13 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:
 The reason that it's not shared is because Sean Kelly didn't 
 want to make
 much of anything in druntime shared until shared was better 
 ironed out, which
 keeps getting talked about but never done.
Yep. There was a fairly productive (brief) discussion on shared in digitalmars.D recently, but no one who can really make such decisions weighed in. I honestly don't know when shared will get a serious look, despite it being probably the most significant unfinished language feature in D 2.0.
Oct 28 2014