Member variables in method are null when called as delegate from thread

Steven Schveighoffer schveiguy at gmail.com
Tue Jan 12 14:00:11 UTC 2021


On 1/11/21 8:49 PM, tsbockman wrote:
> On Monday, 11 January 2021 at 00:43:00 UTC, Tim wrote:
>> 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
> 
> The compiler and the physical CPU are both allowed to change the order 
> in which instructions are executed to something different from what your 
> code specifies, as long as the visible, "official" results and effects 
> of the chosen order of execution are the same as those of your specified 
> code, FROM THE PERSPECTIVE OF THE EXECUTING THREAD.
> 
> This is allowed so that the compiler can optimize to minimize negative 
> "unofficial" effects such as the passage of time and memory consumption.
> 
> However, this re-ordering IS permitted to freely alter the behavior of 
> your code from the perspective of OTHER threads. A likely cause of your 
> bug is that the write to db by the constructor's thread is being 
> committed to memory after the read of db by the MessageService thread.

I don't think this is valid.

1. the compiler MUST NOT reorder the storage of db to after you pass a 
delegate into an opaque function (array allocation).
2. The CPU is not going to reorder, because the memory allocation is 
going to take a global lock anyway (mutex locks should ensure memory 
consistency).

I think something weird is going on, but I don't know what.

> In order to RELIABLY fix this kind of problem, you must correctly use 
> the only commands which the compiler and CPU are NOT allowed to reorder 
> with respect to other threads, namely atomic operations, memory barriers 
> and synchronization primitives.

I can't ever imagine creating a thread (which is likely what 
MessageService ctor is doing) to not have a consistent memory with the 
creating thread on construction. Why would the other thread not see the 
same memory when it didn't exist before? The CPU would have to go out of 
its way to make it inconsistent.

-Steve


More information about the Digitalmars-d-learn mailing list