Member variables in method are null when called as delegate from thread
Arafel
er.krali at gmail.com
Mon Jan 11 08:21:21 UTC 2021
On 11/1/21 1:43, Tim wrote:
> Hi there,
>
> I have something like this:
>
> class Foo{
> MongoClient db;
>
> this(){
> db = connectMongoDB("127.0.0.1");
> void delegate()[string] commands = ["start": &this.start];
> MessageService messenger = new MessageService(8081, commands);
> }
>
> void start(){
> // Do something with db
> }
>
> MessageService is a thread that deals with socket communication. When a
> command comes in, it calls the appropriate delegate given to it by
> commands. When MessageService calls the delegate for start, db is null.
> If I call start() in the Foo constructor it works just fine. Am I
> missing something here? Do delegates get called outside of their class
> context? I know I could just pass the db into start but I want to work
> out exactly why this is happening
>
> Thanks in advance
Hi,
Member variables are thread-local by default. At the very least you'll
need to make `db` `shared` and manually verify that it's safe to use
them before casting it away. So your code could end up a bit like this:
```
class Foo{
shared MongoClient db;
this(){
db = cast (shared) connectMongoDB("127.0.0.1");
void delegate()[string] commands = ["start": &this.start];
MessageService messenger = new MessageService(8081, commands);
}
void start(){
// Make sure there's no other thread accessing the db
// If db is a class, you'll be able to use `db_`:
auto db_ = cast () db;
// Otherwise you'll be making a copy and will have to use
`cast() db` each time, or make a nasty workaround with pointers.
}
}
```
It's also possible that you'll have to make Foo itself `shared`, or at
least convert your constructor into a `shared this ()` to get a shared
instance that you can pass to a different thread, but I'm not sure how
function pointers / delegates work across threads.
Best,
A.
More information about the Digitalmars-d-learn
mailing list