On 05/30/12 17:50, Steven Schveighoffer wrote: > So I propose it does this instead (entirely via lowering): > > synchronized(x) > { > } > > translates to: > > auto l = x.__getMutex(); > l.lock(); > try > { > } > finally > { > l.unlock(); > }
I like this, it's slightly more complex, but can reduce the amount of boilerplate (by not requiring lock/unlock forwarders etc) and is more powerful than my proposal. > So we have a few benefits here: > > 1. if typeof(x) does not define __getMutex, the above is a compiler error. > 2. We can control the visibility of the mutex, because we can attribute > private or protected to the __getMutex function. > 3. We can control what kinds of objects of typeof(x) use mutexes. e.g. > define __getMutex() shared only. > 4. We have control over the type of the lock, it can be anything and does not > need to fit into some runtime function's interface. 5. The lock doesn't have to be a real lock, but eg a lock manager. Hmm, lowering to l.lock(x) and l.unlock(x) might be better; inlining will make it zero-cost for the simple case, but this will make certain schemes much simplier (no need to encode 'x' inside the returned 'l'). > Second, I propose a somewhat gradual transition. I think on first release, > we *still* keep the allocated word in the class instance, and keep the > druntime function which lazily allocates the mutex. Therefore, changing an > object that currently *properly* can use synchronized(this) can be made to > work: > > class Synchronizable > { > xxx __getMutex() shared { return _d_getObjectMonitor(this);} > } > > We can deprecate that functionality, and the allocated space for the mutex > later if desired. Yes, UFCS could help too. artur