Thread overview
sending shared pointer to struct. message type mismatch
Apr 21, 2016
jacob
Apr 21, 2016
Ali Çehreli
Apr 21, 2016
ag0aep6g
Apr 21, 2016
jacob
April 21, 2016
Hello!

I try to send shared pointer to struct:

[code]
import std.stdio;
import std.concurrency;

shared struct S(T, uint M)
{
	T[M] x;
}

shared struct M
{
	int x;
}


private void runner(T)()
{
	shared(T*) s = receiveOnly!(shared(T*))();
	writeln(s.x.length);
	writeln(s.x[0]);
	send(thisTid, true);
}

int main(string[] argv)
{
	alias S!(M, 2) TS;
	alias shared(TS*) PS;

	Tid runnerTid = spawn(&runner!(TS));

	auto s = new shared(TS);
	s.x[0] = M(42);
	send(runnerTid, s);

	bool ok = receiveOnly!bool();

	return 0;
}
[/code]

But after evaluating line "shared(T*) s = receiveOnly!(shared(T*))();" I get an exception:

"First-chance exception: std.concurrency.MessageMismatch Unexpected message type: expected 'shared(S!(M, 2u)*)', got 'shared(engine.S!(M, 2u).S)*' at std\concurrency.d(224)"

How can I pass shared pointer to "runner" thread correctly?
April 21, 2016
On 4/21/16 1:10 PM, jacob wrote:
> import std.stdio;
> import std.concurrency;
>
> shared struct S(T, uint M)
> {
>      T[M] x;
> }
>
> shared struct M
> {
>      int x;
> }
>
>
> private void runner(T)()
> {
>      shared(T*) s = receiveOnly!(shared(T*))();
>      writeln(s.x.length);
>      writeln(s.x[0]);
>      send(thisTid, true);
> }
>
> int main(string[] argv)
> {
>      alias S!(M, 2) TS;
>      alias shared(TS*) PS;
>
>      Tid runnerTid = spawn(&runner!(TS));
>
>      auto s = new shared(TS);
>      s.x[0] = M(42);
>      send(runnerTid, s);
>
>      bool ok = receiveOnly!bool();
>
>      return 0;
> }

I get strange behavior. Not an error/exception, but basically hung process. I tried modifying different things, and passing other types of messages. Seems almost like the call to send is ignored for sending the s message.

Tried various things, but receiveOnly appears broken for me. I've sent messages that should cause an exception and it just hangs.

-Steve
April 21, 2016
On 21.04.2016 19:10, jacob wrote:
> private void runner(T)()
> {
>      shared(T*) s = receiveOnly!(shared(T*))();

This tries to receive a `shared(S!(M, 2)*)`.

>      writeln(s.x.length);
>      writeln(s.x[0]);
>      send(thisTid, true);

Aside: Should be `ownerTid` here, no?

> }
>
> int main(string[] argv)

Aside: If you don't use them, you don't need to the `int` return type and parameter on main. A `void main()` works just fine.

> {
>      alias S!(M, 2) TS;
>      alias shared(TS*) PS;

Aside: preferred syntax nowadays is `alias TS = S!(M, 2);`.

>
>      Tid runnerTid = spawn(&runner!(TS));
>
>      auto s = new shared(TS);

This creates a `shared(S!(M, 2))*`, which is not exactly the same as `shared(S!(M, 2)*)`. The pointer is not shared in the former, but it is shared in the latter.

I was going to suggest either sending a `shared(TS*)` or receiving a `shared(T)*`. But it looks like you can't send a shared pointer. When I tried, it got turned into a unshared-pointer-to-shared on the way.

Changing it to `shared(T)*` on the receiving end works, though. Do that, I guess.

>      s.x[0] = M(42);
>      send(runnerTid, s);
>
>      bool ok = receiveOnly!bool();
>
>      return 0;
> }

April 21, 2016
On Thursday, 21 April 2016 at 17:33:32 UTC, ag0aep6g wrote:
> On 21.04.2016 19:10, jacob wrote:
> I was going to suggest either sending a `shared(TS*)` or receiving a `shared(T)*`. But it looks like you can't send a shared pointer. When I tried, it got turned into a unshared-pointer-to-shared on the way.

Oh that tricky "shared" keyword... Thank you!

http://pastebin.com/YkZ3YzKG fixed version here
April 21, 2016
On 4/21/16 1:33 PM, ag0aep6g wrote:

> This creates a `shared(S!(M, 2))*`, which is not exactly the same as
> `shared(S!(M, 2)*)`. The pointer is not shared in the former, but it is
> shared in the latter.
>
> I was going to suggest either sending a `shared(TS*)` or receiving a
> `shared(T)*`. But it looks like you can't send a shared pointer. When I
> tried, it got turned into a unshared-pointer-to-shared on the way.

Yes, because Unqual will remove the shared from the type (this is a normalization of sorts, to help this kind of situation).

> Changing it to `shared(T)*` on the receiving end works, though. Do that,
> I guess.

This does and doesn't make sense. If you receive a shared(T)*, you should be able to receive it into a shared(T*). However, it's possible the library doesn't put this together.

-Steve
April 21, 2016
On 4/21/16 1:29 PM, Steven Schveighoffer wrote:

> I get strange behavior. Not an error/exception, but basically hung
> process. I tried modifying different things, and passing other types of
> messages. Seems almost like the call to send is ignored for sending the
> s message.

Nevermind, this is my ignorance. I was unaware that a spawned thread terminating via uncaught exception does nothing.

It kind of makes sense, but definitely not what many would expect.

-Steve
April 21, 2016
On 04/21/2016 02:15 PM, Steven Schveighoffer wrote:

> I was unaware that a spawned thread
> terminating via uncaught exception does nothing.
>
> It kind of makes sense, but definitely not what many would expect.

In case it's useful to others, there is something written about it here:


http://ddili.org/ders/d.en/concurrency.html#ix_concurrency.exception,%20concurrency

Ali