Re: synchronized/shared associative array .require error

2022-09-06 Thread frame via Digitalmars-d-learn

On Tuesday, 6 September 2022 at 10:28:53 UTC, Loara wrote:

On Saturday, 3 September 2022 at 14:07:58 UTC, frame wrote:
Not exactly, a synchronized class member function becomes 
automatically a shared one.


This is not present in official documentation so other 
compilers different from `dmd` aren't forced to assume it. This 
should be consider an experimental feature of D that users 
should be able to turn off if they want.


Hmm.. LDC does the same to me.

I think the whole synchronization class is an experimental 
feature :D




Re: synchronized/shared associative array .require error

2022-09-06 Thread Loara via Digitalmars-d-learn

On Saturday, 3 September 2022 at 14:07:58 UTC, frame wrote:
Not exactly, a synchronized class member function becomes 
automatically a shared one.


This is not present in official documentation so other compilers 
different from `dmd` aren't forced to assume it. This should be 
consider an experimental feature of D that users should be able 
to turn off if they want.





Re: synchronized/shared associative array .require error

2022-09-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/4/22 11:24 PM, cc wrote:

On Saturday, 3 September 2022 at 14:37:16 UTC, Steven Schveighoffer wrote:

On 9/2/22 3:15 PM, cc wrote:

Tried casting away shared as a workaround but I assume that will 
cause some kind of TLS catastrophe.




I think it will be fine, but you may have an issue. You are returning 
a non-shared `VAL`, but your class is `shared`, which means `table`, 
and all the `VAL` and `KEY` inside must also be `shared`.


If you cast away `shared` you have to put it back upon return.

TLS should not be involved here at all, so there is no problem there.



Alright, so this is safe then?
```d
alias VAL[KEY] T;
auto require(KEY key) {
 auto unsharedT = cast(T) table;
 auto r = unsharedT.require(key);
 table = cast(shared) unsharedT;
 return cast(shared) r;
}
```


I think that is fine-ish. You still don't have a shared `KEY` there. But 
it really depends on what KEY is. Most likely it's fine (e.g. if `KEY` 
is string). If you don't ever really fetch anything out of the key, and 
just use it to map to your values, I think it should be fine.


Was a bit surprised to see mutating `unsharedT` left `table` unchanged 
and needed reassigning.


Yes, because before an AA contains an element, it is a `null` AA. When 
you add the first element, it's allocated. When you make a copy of a 
`null` AA, it doesn't affect the original.


You can fix this by reinterpret casting the AA instead of copying it:

```d
auto r = .require(*(cast(T*)&table), key);
// I think this might also work:
auto r = (cast()table).require(key);
```

-Steve


Re: synchronized/shared associative array .require error

2022-09-04 Thread cc via Digitalmars-d-learn
On Saturday, 3 September 2022 at 14:37:16 UTC, Steven 
Schveighoffer wrote:

On 9/2/22 3:15 PM, cc wrote:

Tried casting away shared as a workaround but I assume that 
will cause some kind of TLS catastrophe.




I think it will be fine, but you may have an issue. You are 
returning a non-shared `VAL`, but your class is `shared`, which 
means `table`, and all the `VAL` and `KEY` inside must also be 
`shared`.


If you cast away `shared` you have to put it back upon return.

TLS should not be involved here at all, so there is no problem 
there.


-Steve


Alright, so this is safe then?
```d
alias VAL[KEY] T;
auto require(KEY key) {
auto unsharedT = cast(T) table;
auto r = unsharedT.require(key);
table = cast(shared) unsharedT;
return cast(shared) r;
}
```
Was a bit surprised to see mutating `unsharedT` left `table` 
unchanged and needed reassigning.


Re: synchronized/shared associative array .require error

2022-09-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/2/22 3:15 PM, cc wrote:

Tried casting away shared as a workaround but I assume that will cause 
some kind of TLS catastrophe.




I think it will be fine, but you may have an issue. You are returning a 
non-shared `VAL`, but your class is `shared`, which means `table`, and 
all the `VAL` and `KEY` inside must also be `shared`.


If you cast away `shared` you have to put it back upon return.

TLS should not be involved here at all, so there is no problem there.

-Steve


Re: synchronized/shared associative array .require error

2022-09-03 Thread frame via Digitalmars-d-learn

On Saturday, 3 September 2022 at 09:49:54 UTC, Loara wrote:

In current version of D language `synchronized` and `shared` 
are independent. In particular `shared` should be used only for 
basic types like integers for which atomic operations are well 
defined, and not for classes.


Not exactly, a synchronized class member function becomes 
automatically a shared one.


Re: synchronized/shared associative array .require error

2022-09-03 Thread Loara via Digitalmars-d-learn

On Friday, 2 September 2022 at 19:15:45 UTC, cc wrote:

```d
synchronized class SyncTable(KEY, VAL) {
private VAL[KEY] table;
auto require(KEY key) {
return table.require(key);
}
}

auto table = new shared SyncTable!(string, string);
table.require("abc");
```

Fails to compile:
```
// Error: none of the overloads of template `object.require` 
are callable using argument types `!()(shared(string[string]), 
string)`

```

Tried casting away shared as a workaround but I assume that 
will cause some kind of TLS catastrophe.


In current version of D language `synchronized` and `shared` are 
independent. In particular `shared` should be used only for basic 
types like integers for which atomic operations are well defined, 
and not for classes.


Anyway if you must send a reference of a `synchronized` class to 
a different thread then it's safe to cast `shared` and then 
remove it later:


```d
synchronized class A{
...
}

void sendTo(Tid to, A a){
  to.send(cast(shared A) a);
}

A receiveA(){
  A a;
  receive( (shared A sa) { a = cast(A) sa; });
  return a;
}
```

Unfortunately there isn't any traits that tells you if a class is 
`synchronized` or not, so you can't do a safe template function 
for this.


synchronized/shared associative array .require error

2022-09-02 Thread cc via Digitalmars-d-learn

```d
synchronized class SyncTable(KEY, VAL) {
private VAL[KEY] table;
auto require(KEY key) {
return table.require(key);
}
}

auto table = new shared SyncTable!(string, string);
table.require("abc");
```

Fails to compile:
```
// Error: none of the overloads of template `object.require` are 
callable using argument types `!()(shared(string[string]), 
string)`

```

Tried casting away shared as a workaround but I assume that will 
cause some kind of TLS catastrophe.