Sent: Friday, August 11, 2017 at 5:51 AM From: "Tim Mackinnon" <tim@testit.works> To: "Any question about pharo is welcome" <pharo-users@lists.pharo.org> Subject: Re: [Pharo-users] Thread-safe initialization of class state (was Re: Threads safety in Pharo)
Interesting, your example was subtle enough that I had to read it a few times to understand the issue. (I was caught up on the ifNil and not the contents).
That's the problem. They're close enough that someone could mistakenly refactor the correct code into the incorrect code--and that code would be perfectly fine for lazy initialization of instance state in a non-concurrent class. That's why I always insert a small comment before explaining why it was written that way.
Actually, thinking about it - isn't the real issue the #ifNil - you want an atomic version.
It strikes me you could wrap the whole concept into something like an AtomicLazyVariable? E.g.
initialise fileTypes := AtomicLazyVariable using: [
Dictionary new at: 'txt' put: 'Text File'; at: 'html' put: 'Web Page'; yourself ].
Then have something
fileTypes ^fileTypes value
Where you have a critical section in #value?
Tim
Sent from my iPhone On 11 Aug 2017, at 07:53, monty <monty2@programmer.net[mailto:monty2@programmer.net]> wrote:
Here's a hypothetical broken class method that does lazy initialization of a class inst var:
fileTypes fileTypes ifNil: [ fileTypes := Dictionary new. fileTypes at: 'txt' put: 'Text File'; at: 'html' put: 'Web Page'; at: 'pdf' put: 'Portable Document Format File'; at: 'doc' put: 'Microsoft Word Document']. ^ fileTypes.
Because the assignment is done first and the initialization is done after with a cascade of interruptable sends of #at:put:, there's a window after the assignment where 'fileTypes' is not nil but also not fully initialized--a race condition.
The fix is simple. Do the initialization before the atomic assignment takes place, so the var is only ever bound to nil or a fully initialized object:
fileTypes fileTypes ifNil: [ fileTypes := Dictionary new at: 'txt' put: 'Text File'; at: 'html' put: 'Web Page'; at: 'pdf' put: 'Portable Document Format File'; at: 'doc' put: 'Microsoft Word Document'; yourself]. ^ fileTypes.
The fixed code is still vulnerable to duplicate initialization, because the initialization sequence is interruptable and 'fileTypes' is nil during it, but as long as the initialization is cheap enough, has no side effects that restrict how often it can be done, and it's enough that the initialized objects are equal (but not identical), that's OK.
If it's too complex for a single statement, you can use a temp vars or put it in a separate factory method:
fileTypes fileTypes ifNil: [ fileTypes := self newFileTypes]. ^ fileTypes.
Similar precautions (given how easy) might as well be taken with explicit initialization of class state too. Of course if the object is mutated later (in other methods), then Mutexes or other constructs are needed to guard access. But for immutable class state, ensuring initialization is done before assignment should be enough. Sent: Tuesday, August 01, 2017 at 7:36 AMFrom: "Stephane Ducasse" <stepharo.self@gmail.com[mailto:stepharo.self@gmail.com]>To: "Any question about pharo is welcome" <pharo-users@lists.pharo.org[mailto:pharo-users@lists.pharo.org]>Subject: Re: [Pharo-users] Threads safety in Pharo I would love to have an analysis of assumptions made in some code.Because my impression is that the concurrent code is sometimes definedknowing the underlying logic of scheduler and this is not good.As I said to abdel privately in french it would be great to start frommy french squeak book (Yes I wrote one long time ago) chapter onconcurrent programming and turn it into a pharo chapter. Stef On Tue, Aug 1, 2017 at 1:31 PM, Ben Coman <btc@openinworld.com[mailto:btc@openinworld.com]> wrote:Not sure I'll have what you're looking for, but to start, do you meanPharo's green threads or vm native threads?cheers -ben On Mon, Jul 31, 2017 at 7:38 AM, Alidra Abdelghani via Pharo-users<pharo-users@lists.pharo.org[mailto:pharo-users@lists.pharo.org]> wrote: ---------- Forwarded message ----------From: Alidra Abdelghani <alidrandco@yahoo.fr[mailto:alidrandco@yahoo.fr]>To: pharo-users@lists.pharo.org[mailto:pharo-users@lists.pharo.org]Cc: "Stéphane Ducasse" <stephane.ducasse@inria.fr[mailto:stephane.ducasse@inria.fr]>, farid arfi<arfi_f@hotmail.com[mailto:arfi_f@hotmail.com]>Bcc:Date: Mon, 31 Jul 2017 01:38:58 +0200Subject: Threads safety in PharoHi, Somebody once evoked the problem of threads safety in Pharo. With a friendof mine who is expert in formal methods and process scheduling, we wouldlike to have a look on it.Does anyone knows a good document describing the problem of Pharo withthreads safety or at least any document that we can start with? Thanks in advance,Abdelghani