www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cannot take the .keys of shared AA. Is this a regression in 2.087 or a

reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
Code:

import std;

shared(string[string]) dict;

void main()
{
     dict.keys;
}

Error:

/dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3417): 
Error: cannot implicitly convert expression aa of type 
shared(string[string]) to const(shared(string)[string])
onlineapp.d(7): Error: template instance 
`object.keys!(shared(string[string]), shared(string), string)` 
error instantiating

Before D 2.087 it compiled - is this a regression?
Aug 15 2019
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
n Thursday, August 15, 2019 11:33:06 AM MDT Piotr Mitana via Digitalmars-d-
learn wrote:
 Code:

 import std;

 shared(string[string]) dict;

 void main()
 {
      dict.keys;
 }

 Error:

 /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3417):
 Error: cannot implicitly convert expression aa of type
 shared(string[string]) to const(shared(string)[string])
 onlineapp.d(7): Error: template instance
 `object.keys!(shared(string[string]), shared(string), string)`
 error instantiating

 Before D 2.087 it compiled - is this a regression?
Not being able to implicitly convert to const is a bit odd, but arguably, nothing should ever be called on a shared AA anyway. If an operation isn't thread-safe, then it shouldn't work with shared. To use a shared object safely, you have to protect access to it with a mutex or some other synchronization mechanism, after which you would normally cast away shared to operate on the object as thread-local while the lock is in place and then release the lock when you're done (also making sure that no thread-local references exist when the lock is released). Because keys is not at all thread-safe, I'd strongly argue that it should not work on a shared AA, and if it does, that's a bug. - Jonathan M Davis
Aug 15 2019
next sibling parent bauss <jj_1337 live.dk> writes:
On Thursday, 15 August 2019 at 19:51:30 UTC, Jonathan M Davis 
wrote:
 n Thursday, August 15, 2019 11:33:06 AM MDT Piotr Mitana via 
 Digitalmars-d- learn wrote:
 Code:

 import std;

 shared(string[string]) dict;

 void main()
 {
      dict.keys;
 }

 Error:

 /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3417):
 Error: cannot implicitly convert expression aa of type
 shared(string[string]) to const(shared(string)[string])
 onlineapp.d(7): Error: template instance
 `object.keys!(shared(string[string]), shared(string), string)`
 error instantiating

 Before D 2.087 it compiled - is this a regression?
Not being able to implicitly convert to const is a bit odd, but arguably, nothing should ever be called on a shared AA anyway. If an operation isn't thread-safe, then it shouldn't work with shared. To use a shared object safely, you have to protect access to it with a mutex or some other synchronization mechanism, after which you would normally cast away shared to operate on the object as thread-local while the lock is in place and then release the lock when you're done (also making sure that no thread-local references exist when the lock is released). Because keys is not at all thread-safe, I'd strongly argue that it should not work on a shared AA, and if it does, that's a bug. - Jonathan M Davis
D really needs some official thread-safe implementations of containers, hashmaps etc.
Aug 15 2019
prev sibling parent reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Thursday, 15 August 2019 at 19:51:30 UTC, Jonathan M Davis 
wrote:
 Not being able to implicitly convert to const is a bit odd, but 
 arguably, nothing should ever be called on a shared AA anyway. 
 If an operation isn't thread-safe, then it shouldn't work with 
 shared. To use a shared object safely, you have to protect 
 access to it with a mutex or some other synchronization 
 mechanism, after which you would normally cast away shared to 
 operate on the object as thread-local while the lock is in 
 place and then release the lock when you're done (also making 
 sure that no thread-local references exist when the lock is 
 released). Because keys is not at all thread-safe, I'd strongly 
 argue that it should not work on a shared AA, and if it does, 
 that's a bug.
OK, I get the point. So I should go with something similar to this, right? import core.sync.mutex; import std; shared(string[string]) dict; shared(Mutex) mtx; shared static this() { mtx = new shared Mutex; } void main() { mtx.lock; (cast(string[string]) dict).keys; mtx.unlock; } Or I could use synchronized, if dict was inside a class. Thank you!
Aug 16 2019
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, August 16, 2019 2:16:31 AM MDT Piotr Mitana via Digitalmars-d-
learn wrote:
 On Thursday, 15 August 2019 at 19:51:30 UTC, Jonathan M Davis

 wrote:
 Not being able to implicitly convert to const is a bit odd, but
 arguably, nothing should ever be called on a shared AA anyway.
 If an operation isn't thread-safe, then it shouldn't work with
 shared. To use a shared object safely, you have to protect
 access to it with a mutex or some other synchronization
 mechanism, after which you would normally cast away shared to
 operate on the object as thread-local while the lock is in
 place and then release the lock when you're done (also making
 sure that no thread-local references exist when the lock is
 released). Because keys is not at all thread-safe, I'd strongly
 argue that it should not work on a shared AA, and if it does,
 that's a bug.
OK, I get the point. So I should go with something similar to this, right? import core.sync.mutex; import std; shared(string[string]) dict; shared(Mutex) mtx; shared static this() { mtx = new shared Mutex; } void main() { mtx.lock; (cast(string[string]) dict).keys; mtx.unlock; } Or I could use synchronized, if dict was inside a class. Thank you!
Yes. Or you can use synchronized blocks. e.g. synchronized(mtx) { (cast(string[string]) dict).keys; } - Jonathan M Davis
Aug 16 2019