digitalmars.D - Get a Reference to an Object's Monitor
- Andrew Wiley (52/52) Dec 20 2011 Is there any way to get a reference to an object's monitor? This would
- bearophile (4/7) Dec 20 2011 Bye,
- Andrew Wiley (10/15) Dec 20 2011 I've seen that, but using the built-in monitor explicitly in a few
- bearophile (6/9) Dec 20 2011 I see.
- Timon Gehr (8/17) Dec 20 2011 The vptr is used to implement dynamic method calls. Therefore it might
- bearophile (8/17) Dec 20 2011 To quickly know what's the class of a class instance that's on the heap,...
- Timon Gehr (11/26) Dec 20 2011 __vptr is not even a documented feature, so your request seems strange
- Timon Gehr (2/4) Dec 20 2011 Ok, seems it is in the docs.
- Andrew Wiley (25/31) Dec 20 2011 this(Object o);
- Sean Kelly (4/40) Dec 20 2011 Yup.=20
- Andrew Wiley (8/9) Dec 20 2011 Do you have any plans to eliminate the fun things like
- Sean Kelly (3/15) Dec 20 2011 I agree. I really need to fix this.
Is there any way to get a reference to an object's monitor? This would be very useful because a Condition has to be tied to a Mutex, and since objects already have a reference to a Mutex built in, it doesn't make much sense to create another (and add another reference to the class) when the end effect is the same. Example: --- class Example { private: Mutex _lock; Condition _condition; public this() { _lock = new Mutex(); _condition = new Condition(_lock); } void methodA() shared { synchronized(_lock) { // do some stuff while(someTest) _condition.wait(); } } void methodB() shared { synchronized(_lock) { //do some stuff _condition.notifyAll(); } } } --- If I could get a reference to Example's monitor, this example becomes: --- synchronized class Example { private: Condition _condition; public this() { _condition = new Condition(this.__monitor); } void methodA() { // do some stuff while(someTest) _condition.wait(); } void methodB() { //do some stuff _condition.notifyAll(); } } --- Which is much more fool-proof to write.
Dec 20 2011
Andrew Wiley:Is there any way to get a reference to an object's monitor?Is this useful? From the D2 docs:The properties .__vptr and .__monitor give access to the class object's vtbl[] and monitor, respectively, but should not be used in user code.Bye, bearophile
Dec 20 2011
On Tue, Dec 20, 2011 at 2:29 PM, bearophile <bearophileHUGS lycos.com> wrote:Andrew Wiley:I've seen that, but using the built-in monitor explicitly in a few places means it's much harder to make mistakes like locking the wrong lock or forgetting to lock altogether. In my two code examples, the first one is much easier to screw up as the class gets larger and larger because marking methods as "shared" eliminates any guarantees the compiler can provide. I suspect the reason they advise not using it in user code is that the monitor is lazily initialized (if I remember correctly), so I'd have to initialize it myself.Is there any way to get a reference to an object's monitor?Is this useful? From the D2 docs:The properties .__vptr and .__monitor give access to the class object's vtbl[] and monitor, respectively, but should not be used in user code.
Dec 20 2011
Andrew Wiley:I suspect the reason they advise not using it in user code is that the monitor is lazily initialized (if I remember correctly), so I'd have to initialize it myself.I see. I have a question myself. Regarding this, do you know why __vptr is an instance attribute instead of a class attribute? http://d.puremagic.com/issues/show_bug.cgi?id=3939 Bye, bearophile
Dec 20 2011
On 12/21/2011 12:40 AM, bearophile wrote:Andrew Wiley:The vptr is used to implement dynamic method calls. Therefore it might not correspond to the static type of the reference and has to be an instance attribute. Why would you have to manipulate vptr? You can use typeid to compare instances for identity of their corresponding type. Anyway, to get the vptr of a class C, do this: void** vptr = typeid(C).vtbl.ptr;I suspect the reason they advise not using it in user code is that the monitor is lazily initialized (if I remember correctly), so I'd have to initialize it myself.I see. I have a question myself. Regarding this, do you know why __vptr is an instance attribute instead of a class attribute? http://d.puremagic.com/issues/show_bug.cgi?id=3939 Bye, bearophile
Dec 20 2011
Timon Gehr:The vptr is used to implement dynamic method calls. Therefore it might not correspond to the static type of the reference and has to be an instance attribute.Right. In that old enhancement request I was asking for __vptr to be both a class attribute and instance attribute.Why would you have to manipulate vptr?To quickly know what's the class of a class instance that's on the heap, to avoid structs because I sometimes need virtual methods, and avoid initializing another field just for this purpose. It's for a special usage.You can use typeid to compare instances for identity of their corresponding type.I think I need something more light.Anyway, to get the vptr of a class C, do this: void** vptr = typeid(C).vtbl.ptr;I will compare this to the solution I have used to safe. Creating a class instance of TypeInfo just to know the value of what it looks like a static field (the head of the virtual table) seems strange. Bye, bearophile
Dec 20 2011
On 12/21/2011 01:27 AM, bearophile wrote:Timon Gehr:__vptr is not even a documented feature, so your request seems strange to me.The vptr is used to implement dynamic method calls. Therefore it might not correspond to the static type of the reference and has to be an instance attribute.Right. In that old enhancement request I was asking for __vptr to be both a class attribute and instance attribute.class A{} class B: A{} void main(){ A a = new B; assert(typeid(a) is typeid(B)); }Why would you have to manipulate vptr?To quickly know what's the class of a class instance that's on the heap, to avoid structs because I sometimes need virtual methods, and avoid initializing another field just for this purpose. It's for a special usage.You can use typeid to compare instances for identity of their corresponding type.I think I need something more light.? No class instance is created. typeid just gives a reference to the compiler generated typeinfo that is in the static data section.Anyway, to get the vptr of a class C, do this: void** vptr = typeid(C).vtbl.ptr;I will compare this to the solution I have used to safe. Creating a class instance of TypeInfo just to know the value of what it looks like a static field (the head of the virtual table) seems strange.
Dec 20 2011
On 12/21/2011 02:03 AM, Timon Gehr wrote:__vptr is not even a documented feature, so your request seems strange to me.Ok, seems it is in the docs.
Dec 20 2011
On Tue, Dec 20, 2011 at 3:40 PM, bearophile <bearophileHUGS lycos.com> wrote:Andrew Wiley:It looks like Sean is ahead of me:I suspect the reason they advise not using it in user code is that the monitor is lazily initialized (if I remember correctly), so I'd have to initialize it myself.I see.From core.sync.mutex:this(Object o); Initializes a mutex object and sets it as the monitor for o. So my example would look like: --- synchronized class Example { private: Condition _condition; public this() { auto lock = new Mutex(this); _condition = new Condition(lock); } void methodA() { // do some stuff while(someTest) _condition.wait(); } void methodB() { //do some stuff _condition.notifyAll(); } } ---
Dec 20 2011
Yup.=20 Sent from my iPhone On Dec 20, 2011, at 4:22 PM, Andrew Wiley <wiley.andrew.j gmail.com> wrote:On Tue, Dec 20, 2011 at 3:40 PM, bearophile <bearophileHUGS lycos.com> wro=te:Andrew Wiley: =20=20 It looks like Sean is ahead of me: =46rom core.sync.mutex: =20 this(Object o); Initializes a mutex object and sets it as the monitor for o. =20 So my example would look like: --- synchronized class Example { private: Condition _condition; public this() { auto lock =3D new Mutex(this); _condition =3D new Condition(lock); } void methodA() { // do some stuff while(someTest) _condition.wait(); } void methodB() { //do some stuff _condition.notifyAll(); } } ---I suspect the reason they advise not using it in user code is that the monitor is lazily initialized (if I remember correctly), so I'd have to initialize it myself.=20 I see.
Dec 20 2011
On Tue, Dec 20, 2011 at 9:16 PM, Sean Kelly <sean invisibleduck.org> wrote:Yup.Do you have any plans to eliminate the fun things like (cast()condition).wait(); ? It seems like most of the classes in core.sync should be declared as shared classes. I realize there would be code breakage, but having to cast away shared everywhere I do anything beyond `synchronized` is pretty broken.
Dec 20 2011
I agree. I really need to fix this. Sent from my iPhone On Dec 20, 2011, at 9:44 PM, Andrew Wiley <wiley.andrew.j gmail.com> wrote:On Tue, Dec 20, 2011 at 9:16 PM, Sean Kelly <sean invisibleduck.org> wrote:Yup.Do you have any plans to eliminate the fun things like (cast()condition).wait(); ? It seems like most of the classes in core.sync should be declared as shared classes. I realize there would be code breakage, but having to cast away shared everywhere I do anything beyond `synchronized` is pretty broken.
Dec 20 2011