digitalmars.D.learn - sending shared pointer to struct. message type mismatch
- jacob (38/38) Apr 21 2016 Hello!
- Steven Schveighoffer (8/36) Apr 21 2016 I get strange behavior. Not an error/exception, but basically hung
- Steven Schveighoffer (5/9) Apr 21 2016 Nevermind, this is my ignorance. I was unaware that a spawned thread
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/8) Apr 21 2016 In case it's useful to others, there is something written about it here:
- ag0aep6g (14/32) Apr 21 2016 Aside: Should be `ownerTid` here, no?
- jacob (3/8) Apr 21 2016 Oh that tricky "shared" keyword... Thank you!
- Steven Schveighoffer (7/15) Apr 21 2016 Yes, because Unqual will remove the shared from the type (this is a
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?
Apr 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
Apr 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
Apr 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
Apr 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; }
Apr 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
Apr 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
Apr 21 2016