#include "rr.h" #include "v8_locker.h" using namespace v8; namespace { namespace Lock { /** * Document-method: V8::C::Locker#new * * Allocates and returns a new `v8::Locker` object. The thread that instantiated * this object will hold the V8 interpreter lock until it is released with a * corresponding call to {#delete}. * * It critical that you call {#delete} to deallocate it, preferably within the same method. * If you don't, two bad things will happen: * * 1. You'll leak the underlying C++ object * 1. Worse, you'll leave the V8 vm locked to this thread forever * * It's dangerous! Be sure to `ensure`. * * for detailed semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html} * * @return [V8::C::Locker] the new locker */ VALUE New(VALUE LockerClass) { Locker* locker = new Locker(); return Data_Wrap_Struct(LockerClass, 0, 0, (void*)locker); } /** * Document-method: V8::C::Locker#delete * * Pop this lock off the stack for this thread. For a full run down of V8 locking * semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html} * @return nil */ VALUE Delete(VALUE self) { Locker* locker = 0; Data_Get_Struct(self, class Locker, locker); delete locker; } } namespace Unlock { /** * Document-method: V8::C::Unlocker#new * * Allocates and returns a new `v8::UnLocker` object, temporarily releasing any locks that * this thread is holding. It will reaquire all of the locksto {#delete}. * * This is a great thing to do when you want to call out to some code that might do some * waiting, sleeping, and you want to politely let other threads use this VM. * * It critical that you call {#delete} to deallocate it, preferably within the same method. * If you don't, two bad things will happen: * * 1. You'll leak the underlying C++ object * 1. You won't restore the locks to your current thread, and will mess things up horribly * * It's dangerous! Be sure to `ensure`. * * For details on V8 locking semantics, see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html} * @return [V8::C::Unocker] the new locker */ VALUE New(VALUE UnlockerClass) { Unlocker* unlocker = new Unlocker(); return Data_Wrap_Struct(UnlockerClass, 0, 0, (void*)unlocker); } /** * Document-method: V8::C::Unlocker#delete * * Restore any locks to the stack that were temporarily removed by this `Unlocker`. * For a full run down, see semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html} * @return nil */ VALUE Delete(VALUE self) { Unlocker* unlocker; Data_Get_Struct(self, class Unlocker, unlocker); delete unlocker; } } /** * Document-method: V8::C::Locker#StartPreemption * Start preemption. * When preemption is started, a timer is fired every n milli seconds that will switch between * multiple threads that are in contention for the V8 lock. * * @param [Integer] every_n_ms * @return nil */ VALUE StartPreemption(VALUE self, VALUE every_n_ms) { Locker::StartPreemption(NUM2INT(rb_to_int(every_n_ms))); return Qnil; } /** * Document-method: V8::C::Locker#StartPreemption * Stop preemption */ VALUE StopPreemption(VALUE self) { Locker::StopPreemption(); return Qnil; } /** * Document-method: V8::C::Locker#IsLocked * Returns whether or not the locker is locked by the current thread. */ VALUE IsLocked(VALUE self) { return rr_v82rb(Locker::IsLocked()); } /** * Document-method: V8::C::Locker#IsActive * Returns whether v8::Locker is being used by this V8 instance. */ VALUE IsActive(VALUE self) { return rr_v82rb(Locker::IsActive()); } } void rr_init_v8_locker() { VALUE LockerClass = rr_define_class("Locker"); VALUE UnlockerClass = rr_define_class("Unlocker"); rr_define_singleton_method(LockerClass, "new", Lock::New, 0); rr_define_method(LockerClass, "delete", Lock::Delete, 0); rr_define_singleton_method(UnlockerClass, "new", Unlock::New, 0); rr_define_method(UnlockerClass, "delete", Unlock::Delete, 0); rr_define_singleton_method(LockerClass, "StartPreemption", StartPreemption, 1); rr_define_singleton_method(LockerClass, "StopPreemption", StopPreemption, 0); rr_define_singleton_method(LockerClass, "IsLocked", IsLocked, 0); rr_define_singleton_method(LockerClass, "IsActive", IsActive, 0); }