digitalmars.D.learn - What is the point of a synchronized lock on a single return statement?
- Andrej Mitrovic (15/15) Nov 25 2019 From:
- Jonathan M Davis (7/23) Nov 25 2019 It ensures that no other code that locks m_lock is running when m_closed...
- Andrea Fontana (5/30) Nov 25 2019 Probably to be sure to have a consistent status returned. See for
- angel (17/32) Nov 25 2019 I think this code can be rewritten as
- Steven Schveighoffer (11/29) Nov 25 2019 Locks ensure the CPU and compiler use the correct memory model. It's
- Robert Schadek (24/24) Nov 25 2019 But be aware, even though the bool is returned from a
From: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8c03/std/concurrency.d#L1913-L1916: ----- /// final property bool isClosed() safe nogc pure { synchronized (m_lock) { return m_closed; } } ----- I don't understand the purpose of this lock. The lock will be released as soon as the function returns, and it returns a copy of a boolean anyway. Am I missing something here?
Nov 25 2019
On Monday, November 25, 2019 1:22:17 AM MST Andrej Mitrovic via Digitalmars- d-learn wrote:From: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8 c03/std/concurrency.d#L1913-L1916: ----- /// final property bool isClosed() safe nogc pure { synchronized (m_lock) { return m_closed; } } ----- I don't understand the purpose of this lock. The lock will be released as soon as the function returns, and it returns a copy of a boolean anyway. Am I missing something here?It ensures that no other code that locks m_lock is running when m_closed is accessed. I'd have to study std.concurrency in detail to know for sure why that would be needed, but it's not atypical when trying to maintain consistent state when multiple threads are interacting with each other. - Jonathan M Davis
Nov 25 2019
On Monday, 25 November 2019 at 09:24:43 UTC, Jonathan M Davis wrote:On Monday, November 25, 2019 1:22:17 AM MST Andrej Mitrovic via Digitalmars- d-learn wrote:Probably to be sure to have a consistent status returned. See for example: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8c03/std/concurrency.d#L2250From: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8 c03/std/concurrency.d#L1913-L1916: ----- /// final property bool isClosed() safe nogc pure { synchronized (m_lock) { return m_closed; } } ----- I don't understand the purpose of this lock. The lock will be released as soon as the function returns, and it returns a copy of a boolean anyway. Am I missing something here?It ensures that no other code that locks m_lock is running when m_closed is accessed. I'd have to study std.concurrency in detail to know for sure why that would be needed, but it's not atypical when trying to maintain consistent state when multiple threads are interacting with each other. - Jonathan M Davis
Nov 25 2019
On Monday, 25 November 2019 at 08:22:17 UTC, Andrej Mitrovic wrote:From: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8c03/std/concurrency.d#L1913-L1916: ----- /// final property bool isClosed() safe nogc pure { synchronized (m_lock) { return m_closed; } } ----- I don't understand the purpose of this lock. The lock will be released as soon as the function returns, and it returns a copy of a boolean anyway. Am I missing something here?I think this code can be rewritten as --- final property bool isClosed() safe nogc pure { bool ret; synchronized (m_lock) { ret = m_closed; } return ret; } --- Normally, if the memory location of m_closed is aligned, the assignment to 'ret' should be atomic, however if you cannot make assumptions about alignment, the access should be protected.
Nov 25 2019
On 11/25/19 3:22 AM, Andrej Mitrovic wrote:From: https://github.com/dlang/phobos/blob/10b9174ddcadac52f6a1ea532deab3310d3a8c03/std/concur ency.d#L1913-L1916: ----- /// final property bool isClosed() safe nogc pure { synchronized (m_lock) { return m_closed; } } ----- I don't understand the purpose of this lock. The lock will be released as soon as the function returns, and it returns a copy of a boolean anyway. Am I missing something here?Locks ensure the CPU and compiler use the correct memory model. It's complicated, but necessary. Look up Herb Sutter's atomic weapons talk. The key takeaway is that the "gurus" who make compilers and cpus have the rule "If you use mutex locks, the code will behave like you wrote it for all observations". With out the locks, crazy things can happen. Note also, that even though x86 CPUs are atomic for single values without locks, not all CPUs are. However, I think a bool is likely always atomic. But that doesn't mean the compiler or CPU will not reorder your instructions. The locks keep it consistent. -Steve
Nov 25 2019
But be aware, even though the bool is returned from a synchronized block, its actual value has no meaning at all. All the meaning you get out of that bool is that the MessageBox was closed when you called that function. If there is a function in MessageBox that can reopen the instance, you can not assume that the MessageBox is still closed when you read the bool. Assuming your program has more than one thread touching that instance of the MessageBox. Consider ``` auto mb = new MessageBox(); bool c = mb.isClosed(); // this thread gets preempted, and another thread // does something with mb that changes its state if(!c) { // the value of c might not what you expected // start rockets } ``` This problem, at least partly, spawn concepts like Monitors, the Rendezvous concept, Message Passing, and others.
Nov 25 2019