Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add specs for rb_mutex_* C-API methods

  • Loading branch information...
commit 101ea3c253764f6ea0912a4a4d60dde90835afd1 1 parent 677aac9
Dirkjan Bussink dbussink authored
91 spec/ruby/optional/capi/ext/mutex_spec.c
View
@@ -0,0 +1,91 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_MUTEX_NEW
+VALUE mutex_spec_rb_mutex_new(VALUE self) {
+ return rb_mutex_new();
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_LOCKED_P
+VALUE mutex_spec_rb_mutex_locked_p(VALUE self, VALUE mutex) {
+ return rb_mutex_locked_p(mutex);
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_TRYLOCK
+VALUE mutex_spec_rb_mutex_trylock(VALUE self, VALUE mutex) {
+ return rb_mutex_trylock(mutex);
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_LOCK
+VALUE mutex_spec_rb_mutex_lock(VALUE self, VALUE mutex) {
+ return rb_mutex_lock(mutex);
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_UNLOCK
+VALUE mutex_spec_rb_mutex_unlock(VALUE self, VALUE mutex) {
+ return rb_mutex_unlock(mutex);
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_SLEEP
+VALUE mutex_spec_rb_mutex_sleep(VALUE self, VALUE mutex, VALUE timeout) {
+ return rb_mutex_sleep(mutex, timeout);
+}
+#endif
+
+#ifdef HAVE_RB_MUTEX_SYNCHRONIZE
+
+VALUE mutex_spec_rb_mutex_callback(VALUE arg) {
+ return rb_funcall(arg, rb_intern("call"), 0);
+}
+
+VALUE mutex_spec_rb_mutex_synchronize(VALUE self, VALUE mutex, VALUE value) {
+ return rb_mutex_synchronize(mutex, mutex_spec_rb_mutex_callback, value);
+}
+#endif
+
+void Init_mutex_spec() {
+ VALUE cls;
+ cls = rb_define_class("CApiMutexSpecs", rb_cObject);
+
+#ifdef HAVE_RB_MUTEX_NEW
+ rb_define_method(cls, "rb_mutex_new", mutex_spec_rb_mutex_new, 0);
+#endif
+
+#ifdef HAVE_RB_MUTEX_LOCKED_P
+ rb_define_method(cls, "rb_mutex_locked_p", mutex_spec_rb_mutex_locked_p, 1);
+#endif
+
+#ifdef HAVE_RB_MUTEX_TRYLOCK
+ rb_define_method(cls, "rb_mutex_trylock", mutex_spec_rb_mutex_trylock, 1);
+#endif
+
+#ifdef HAVE_RB_MUTEX_LOCK
+ rb_define_method(cls, "rb_mutex_lock", mutex_spec_rb_mutex_lock, 1);
+#endif
+
+#ifdef HAVE_RB_MUTEX_UNLOCK
+ rb_define_method(cls, "rb_mutex_unlock", mutex_spec_rb_mutex_unlock, 1);
+#endif
+
+#ifdef HAVE_RB_MUTEX_SLEEP
+ rb_define_method(cls, "rb_mutex_sleep", mutex_spec_rb_mutex_sleep, 2);
+#endif
+
+#ifdef HAVE_RB_MUTEX_SYNCHRONIZE
+ rb_define_method(cls, "rb_mutex_synchronize", mutex_spec_rb_mutex_synchronize, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
10 spec/ruby/optional/capi/ext/rubyspec.h
View
@@ -306,6 +306,16 @@
#define HAVE_RB_THREAD_FD_WRITABLE 1
#define HAVE_RB_THREAD_WAIT_FD 1
+#ifdef RUBY_VERSION_IS_1_9
+#define HAVE_RB_MUTEX_NEW 1
+#define HAVE_RB_MUTEX_LOCKED_P 1
+#define HAVE_RB_MUTEX_TRYLOCK 1
+#define HAVE_RB_MUTEX_LOCK 1
+#define HAVE_RB_MUTEX_UNLOCK 1
+#define HAVE_RB_MUTEX_SLEEP 1
+#define HAVE_RB_MUTEX_SYNCHRONIZE 1
+#endif
+
/* Kernel */
#define HAVE_RB_BLOCK_GIVEN_P 1
#define HAVE_RB_BLOCK_PROC 1
91 spec/ruby/optional/capi/mutex_spec.rb
View
@@ -0,0 +1,91 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("mutex")
+
+ruby_version_is "1.9" do
+
+ describe "C-API Mutex functions" do
+ before :each do
+ @s = CApiMutexSpecs.new
+ @m = Mutex.new
+ end
+
+ describe "rb_mutex_new" do
+ it "creates a new mutex" do
+ @s.rb_mutex_new.should be_an_instance_of(Mutex)
+ end
+ end
+
+ describe "rb_mutex_locked_p" do
+ it "returns true if the mutex is locked" do
+ @s.rb_mutex_locked_p(@m).should be_false
+ end
+
+ it "returns true if the mutex is locked" do
+ @m.lock
+ @s.rb_mutex_locked_p(@m).should be_true
+ end
+ end
+
+ describe "rb_mutex_trylock" do
+ it "locks the mutex if not locked" do
+ @s.rb_mutex_trylock(@m).should be_true
+ @m.locked?.should be_true
+ end
+
+ it "returns false if the mutex is already locked" do
+ @m.lock
+ @s.rb_mutex_trylock(@m).should be_false
+ @m.locked?.should be_true
+ end
+ end
+
+ describe "rb_mutex_lock" do
+ it "returns when the mutex isn't locked" do
+ @s.rb_mutex_lock(@m).should == @m
+ @m.locked?.should be_true
+ end
+
+ it "throws an exception when already locked in the same thread" do
+ @m.lock
+ lambda { @s.rb_mutex_lock(@m) }.should raise_error(ThreadError)
+ @m.locked?.should be_true
+ end
+ end
+
+ describe "rb_mutex_unlock" do
+ it "raises an exception when not locked" do
+ lambda { @s.rb_mutex_unlock(@m) }.should raise_error(ThreadError)
+ @m.locked?.should be_false
+ end
+
+ it "unlocks the mutex when locked" do
+ @m.lock
+ @s.rb_mutex_unlock(@m).should == @m
+ @m.locked?.should be_false
+ end
+ end
+
+ describe "rb_mutex_sleep" do
+ it "throws an exception when the mutex is not locked" do
+ lambda { @s.rb_mutex_sleep(@m, 0.1) }.should raise_error(ThreadError)
+ @m.locked?.should be_false
+ end
+
+ it "sleeps when the mutex is locked" do
+ @m.lock
+ start = Time.now
+ @s.rb_mutex_sleep(@m, 0.1)
+ (Time.now - start).should be_close(0.1, 0.1)
+ @m.locked?.should be_true
+ end
+ end
+
+ describe "rb_mutex_synchronize" do
+ it "calls the function while the mutex is locked" do
+ callback = lambda { @m.locked?.should be_true }
+ @s.rb_mutex_synchronize(@m, callback)
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.