www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - spawn a function with object as arg?

reply Martin Brezel <martin.brzenska googlemail.com> writes:
I want to create a Client, which receives and handles received 
data in  background while the Client can send via the same socket.

My first idea was something like this:
class Client {
	private Socket socket;
	private Tid receiverTid;

	this(Socket socket) {
		this.socket = socket;
		this.receiverTid = spawn( &receiver, this.socket );
	}
	
	void command(Command[] cmd) {
		this.socket.send(cmd.makeMessage());
	}
}

void receiver(Socket socket) {
	/*..*/
}
..how naive of me :) The compiler says: "Error: static assert: "Aliases to mutable thread-local data not allowed." The documentation for spawn() states: "all arguments to fn must either be shared or immutable or have no pointer indirection." So, now i am thinking about to create a instance of Socket inside the spawned worker and do send and receive via Message Passing between Client and the worker. But, is there another way? I am writing lot of golang lately and i am sure something like `go receive(&socket)` would be valid. Now, i am wondering if there is a similar simple way to do it in dlang.
Mar 04 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 4 March 2020 at 23:37:00 UTC, Martin Brezel wrote:
 The documentation for spawn() states: "all arguments to fn must 
 either be shared or immutable or have no pointer indirection."
The easiest thing to do is to just cast import std.concurrency; import std.socket; void main() { auto s = new Socket(); spawn((shared Socket s_) { Socket s = cast() s_; }, cast(shared) s); } Note the shared argument to the function... then cast AWAY shared inside that function, and cast TO shared when passing the argument. That basically just tricks the compiler. But if you aren't going to actually use the socket from the original thread anymore, it should be perfectly fine to do. (if you do actually share it across threads, using it from both... it would actually probably still be fine - the Socket class is a thin wrapper around OS functions that work with threads. But then you re on your own, the compiler won't help get it right at all. Abandoning the old one isn't really getting compiler help either but it is so easy to do that you prolly won't make a mistake.) You can also not use `spawn` and instead give `new Thread` a try from core.thread. That's totally DIY, the compiler won't even try to help you, but it can be simpler if you know what you're doing and don't need to pass a lot of
Mar 04 2020
parent reply Martin Brezel <martin.brzenska googlemail.com> writes:
On Thursday, 5 March 2020 at 03:04:10 UTC, Adam D. Ruppe wrote:
 You can also not use `spawn` and instead give `new Thread` a 
 try from core.thread.
Thanks for the hint, I didn't notice core.thread at all. I will definitely try it out. Unfortunately the documentation page for core.thread is currently not available.
Mar 05 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 5 March 2020 at 18:10:11 UTC, Martin Brezel wrote:
 Unfortunately the documentation page for core.thread is 
 currently not available.
the official docs are lame, use my fork doc website instead: http://dpldocs.info/experimental-docs/core.thread.html
Mar 05 2020