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