Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I lock on any object type in C#?

Can someone explain, in detail, why it's possible to lock on objects of any type in C#?

I understand what lock is for and how to use it. I know how it expands to Monitor.Enter/Exit. What I'm looking for an explanation of the implementation detail and design considerations.

First of all: What is happening under the hood? For example: are there extra bits in an object instance (like there is for RTTI/vtable) that make it work? Or some kind of lookup table keyed on object references? (If so, how does this interact with the GC?) Or something else? Why don't I have to create an instance of a specific type to hold whatever the lock data is?

(And, by the way, what do Enter and Exit map to in native code?)

And, secondly, why is .NET designed to not have a specific type for taking out locks on? (Given that you generally just make a new object() for the purpose anyway - and most cases where you lock "any old object" are problematic.) Was this design choice forced by the implementation detail? Or was it deliberate? And, if deliberate, was it a good choice? (I realise this second part may require speculation.)

like image 704
Andrew Russell Avatar asked Oct 06 '22 21:10

Andrew Russell


1 Answers

It is possible to lock on all non struct types. In layout of each refernce type on the heap there is special field (sync block) that is used to manage lock. The layout is covered in details in How CLR Creates Runtime Object. Excerpt from article is below:

The OBJECTREF does not point to the beginning of the Object Instance but at a DWORD offset (4 bytes). The DWORD is called Object Header and holds an index (a 1-based syncblk number) into a SyncTableEntry table.

Object layout on the heap:

sync block index 
pointer to type
fields...

Speculation part: I believe that original guidance was to lock on whatever is convinient, but it was relatively quickly changed to having special "private object for lock" due to ease of getting external code to deadlock your methods. I think there even were classes in Framework that were impelented with locking on publically visible objects...

like image 141
Alexei Levenkov Avatar answered Oct 13 '22 10:10

Alexei Levenkov