Re: aa.keys, synchronized and shared

2022-11-14 Thread torhu via Digitalmars-d-learn

On Monday, 14 November 2022 at 07:57:16 UTC, Kagamin wrote:

This works for me:
```
shared SyncAA!(string,string) saa;
void f()
{
saa=new shared SyncAA!(string,string)("1","2");
saa.keys();
saa["12"]="34";
saa.remove("12");
}
```


The strange error message I got was because I initialized the 
variable at module level, that doesn't work when you have a 
constructor. It worked when I moved it into a module constructor.


Re: aa.keys, synchronized and shared

2022-11-14 Thread Kagamin via Digitalmars-d-learn

This works for me:
```
synchronized final class SyncAA(K, V)
{
this(K key, V val) { sharedTable[key]=val; }
V opIndex(K key) { return sharedTable[key]; }
	V opIndexAssign(V value, K key) { return sharedTable[key]=value; 
}

const(K[]) keys() const { return unsharedTable.keys; }
void remove(K key) { sharedTable.remove(key); }
V get(K key, lazy V defaultValue=V.init)
{
auto p = key in sharedTable;
return p ? *p : defaultValue;
}
private:
V[K] sharedTable;
inout(V[K]) unsharedTable() inout
{
return cast(inout(V[K]))sharedTable;
}
}
shared SyncAA!(string,string) saa;
void f()
{
saa=new shared SyncAA!(string,string)("1","2");
saa.keys();
saa["12"]="34";
saa.remove("12");
}
```


Re: aa.keys, synchronized and shared

2022-11-11 Thread torhu via Digitalmars-d-learn

On Friday, 11 November 2022 at 14:19:31 UTC, Kagamin wrote:

Try this:
```



private:
V[K] sharedTable;
ref inout(V[K]) unsharedTable() inout
{
return *cast(inout(V[K])*)
}
```


Thanks, that worked! Feels like programming in C, though. If I 
could figure out how to initialize the AA explicitly, I could 
also remove the ref here. If I just remove the ref, the AA is 
always null. If I try to initialize it in the constructor, I get 
this:


src\syncaa.d(11,5): Error: `_d_monitorenter` cannot be 
interpreted at compile time, because it has no available source 
code


No idea why, it seems to happen if I try to use the AA in the 
constructor at all. Even when I just do `data_.remove(K.init);`


I also tried DMD 2.101.0-rc.1, using the new `new V[K]` syntax, 
same error there.


Re: aa.keys, synchronized and shared

2022-11-11 Thread Kagamin via Digitalmars-d-learn

With allocation:
```
synchronized final class SyncAA(K, V)
{
V opIndex(K key) { return sharedTable[key]; }
	V opIndexAssign(V value, K key) { return sharedTable[key]=value; 
}

const(K[]) keys() const { return unsharedTable.keys; }
void remove(K key) { sharedTable.remove(key); }
V get(K key, lazy V defaultValue=V.init)
{
auto p = key in sharedTable;
return p ? *p : defaultValue;
}
private:
V[K] sharedTable;
ref inout(V[K]) unsharedTable() inout
{
return *cast(inout(V[K])*)
}
}
shared SyncAA!(string,string) saa;
void f()
{
saa=new shared SyncAA!(string,string);
saa.keys();
saa["12"]="34";
saa.remove("12");
}
```


Re: aa.keys, synchronized and shared

2022-11-11 Thread Kagamin via Digitalmars-d-learn

Try this:
```
synchronized final class SyncAA(K, V)
{
V opIndex(K key) { return sharedTable[key]; }
	V opIndexAssign(V value, K key) { return sharedTable[key]=value; 
}

const(K[]) keys() const { return unsharedTable.keys; }
void remove(K key) { sharedTable.remove(key); }
V get(K key, lazy V defaultValue=V.init)
{
auto p = key in sharedTable;
return p ? *p : defaultValue;
}
private:
V[K] sharedTable;
ref inout(V[K]) unsharedTable() inout
{
return *cast(inout(V[K])*)
}
}
void f(shared SyncAA!(string,string) a)
{
a.keys();
a["12"]="34";
a.remove("12");
}
```


Re: aa.keys, synchronized and shared

2022-11-10 Thread cc via Digitalmars-d-learn

On Friday, 11 November 2022 at 01:09:54 UTC, torhu wrote:

On Thursday, 10 November 2022 at 21:55:26 UTC, torhu wrote:

I'm trying to make a more thread-safe wrapper for AA's:

```
synchronized final class SyncAA(K, V) ///


I chose to fix this by just using `synchronized (this)` inside 
each method instead, for now. Still interested in cleaner 
solutions, but I guess synchronized/shared is a bit of a rabbit 
hole...


That's about what I ended up with, and just declaring my 
references __gshared.  I don't know what's going on with 
shared/synchronized but it sounds like it's unfinished and people 
can't agree on what they're actually supposed to mean.  
__gshared, it just works.
Previous thread: [synchronized/shared associative array .require 
error](https://forum.dlang.org/post/hcbrgpmdufjgjtxtu...@forum.dlang.org)
Also: [synchronized - shared but actually 
useful](https://forum.dlang.org/thread/drrlgymevccozrqms...@forum.dlang.org)


```d
class SyncTable(KEY, VAL) {
private VAL[KEY] table;
auto opIndexAssign(VAL value, KEY key) {
synchronized(this) {
return table[key] = value;
}
}
int opApply(int delegate(ref KEY, ref VAL) dg) {
synchronized(this) {
foreach (key, val; table) {
if (dg(key, val)) return 1;
}
return 0;
}
}
auto opBinaryRight(string op)(KEY key) if (op == "in") {
synchronized(this) {
return key in table;
}
}
auto opDispatch(string s, SA...)(SA sargs) {
synchronized(this) {
static if (SA.length == 0) {
mixin(format("return table.%s;", s));
} else {
mixin(format("return table.%s(%s);", s, sargs.stringof[6 .. 
$-1])); // tuple(_param_0)

}
}
}
}
```

With synchronized on the class, I had to do something like:
```d
synchronized class SyncTable(KEY, VAL) {
// Anything that mutates must reassign unshared back to table!
auto opIndexAssign(VAL value, KEY key) {
auto unshared = cast(T) table;
unshared[key] = value;
table = cast(shared) unshared;
return value;
}
auto require(KEY key) {
auto unshared = cast(T) table;
auto r = unshared.require(key);
table = cast(shared) unshared;
return r;
}
/* ... */
}
```
and it just doesn't feel right.

For mutexes without synchronized, there's also:
```d
struct Lock {
private shared Mutex _mtx;
this(shared Mutex mtx) {
_mtx = mtx;
_mtx.lock();
}
this(this) @disable;
~this() {
if (_mtx)
_mtx.unlock();
_mtx = null;
}
}
class SyncTable(KEY, VAL) {
private VAL[KEY] table;
shared Mutex mtx;
this() {
mtx = new shared Mutex;
}
auto opIndexAssign(VAL value, KEY key) {
auto lock = Lock(mtx);
return table[key] = value;
}
/* ... */
}
```



Re: aa.keys, synchronized and shared

2022-11-10 Thread torhu via Digitalmars-d-learn

On Thursday, 10 November 2022 at 21:55:26 UTC, torhu wrote:

I'm trying to make a more thread-safe wrapper for AA's:

```
synchronized final class SyncAA(K, V) ///


I chose to fix this by just using `synchronized (this)` inside 
each method instead, for now. Still interested in cleaner 
solutions, but I guess synchronized/shared is a bit of a rabbit 
hole...