summaryrefslogtreecommitdiff
path: root/ext/monitor
diff options
context:
space:
mode:
Diffstat (limited to 'ext/monitor')
-rw-r--r--ext/monitor/depend162
-rw-r--r--ext/monitor/extconf.rb2
-rw-r--r--ext/monitor/lib/monitor.rb284
-rw-r--r--ext/monitor/monitor.c225
4 files changed, 0 insertions, 673 deletions
diff --git a/ext/monitor/depend b/ext/monitor/depend
deleted file mode 100644
index fe9ec68806..0000000000
--- a/ext/monitor/depend
+++ /dev/null
@@ -1,162 +0,0 @@
-# AUTOGENERATED DEPENDENCIES START
-monitor.o: $(RUBY_EXTCONF_H)
-monitor.o: $(arch_hdrdir)/ruby/config.h
-monitor.o: $(hdrdir)/ruby/internal/anyargs.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-monitor.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-monitor.o: $(hdrdir)/ruby/internal/assume.h
-monitor.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-monitor.o: $(hdrdir)/ruby/internal/attr/artificial.h
-monitor.o: $(hdrdir)/ruby/internal/attr/cold.h
-monitor.o: $(hdrdir)/ruby/internal/attr/const.h
-monitor.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-monitor.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-monitor.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-monitor.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-monitor.o: $(hdrdir)/ruby/internal/attr/error.h
-monitor.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-monitor.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-monitor.o: $(hdrdir)/ruby/internal/attr/format.h
-monitor.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-monitor.o: $(hdrdir)/ruby/internal/attr/noalias.h
-monitor.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-monitor.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-monitor.o: $(hdrdir)/ruby/internal/attr/noinline.h
-monitor.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-monitor.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-monitor.o: $(hdrdir)/ruby/internal/attr/pure.h
-monitor.o: $(hdrdir)/ruby/internal/attr/restrict.h
-monitor.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-monitor.o: $(hdrdir)/ruby/internal/attr/warning.h
-monitor.o: $(hdrdir)/ruby/internal/attr/weakref.h
-monitor.o: $(hdrdir)/ruby/internal/cast.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-monitor.o: $(hdrdir)/ruby/internal/compiler_since.h
-monitor.o: $(hdrdir)/ruby/internal/config.h
-monitor.o: $(hdrdir)/ruby/internal/constant_p.h
-monitor.o: $(hdrdir)/ruby/internal/core.h
-monitor.o: $(hdrdir)/ruby/internal/core/rarray.h
-monitor.o: $(hdrdir)/ruby/internal/core/rbasic.h
-monitor.o: $(hdrdir)/ruby/internal/core/rbignum.h
-monitor.o: $(hdrdir)/ruby/internal/core/rclass.h
-monitor.o: $(hdrdir)/ruby/internal/core/rdata.h
-monitor.o: $(hdrdir)/ruby/internal/core/rfile.h
-monitor.o: $(hdrdir)/ruby/internal/core/rhash.h
-monitor.o: $(hdrdir)/ruby/internal/core/robject.h
-monitor.o: $(hdrdir)/ruby/internal/core/rregexp.h
-monitor.o: $(hdrdir)/ruby/internal/core/rstring.h
-monitor.o: $(hdrdir)/ruby/internal/core/rstruct.h
-monitor.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-monitor.o: $(hdrdir)/ruby/internal/ctype.h
-monitor.o: $(hdrdir)/ruby/internal/dllexport.h
-monitor.o: $(hdrdir)/ruby/internal/dosish.h
-monitor.o: $(hdrdir)/ruby/internal/error.h
-monitor.o: $(hdrdir)/ruby/internal/eval.h
-monitor.o: $(hdrdir)/ruby/internal/event.h
-monitor.o: $(hdrdir)/ruby/internal/fl_type.h
-monitor.o: $(hdrdir)/ruby/internal/gc.h
-monitor.o: $(hdrdir)/ruby/internal/glob.h
-monitor.o: $(hdrdir)/ruby/internal/globals.h
-monitor.o: $(hdrdir)/ruby/internal/has/attribute.h
-monitor.o: $(hdrdir)/ruby/internal/has/builtin.h
-monitor.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-monitor.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-monitor.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-monitor.o: $(hdrdir)/ruby/internal/has/extension.h
-monitor.o: $(hdrdir)/ruby/internal/has/feature.h
-monitor.o: $(hdrdir)/ruby/internal/has/warning.h
-monitor.o: $(hdrdir)/ruby/internal/intern/array.h
-monitor.o: $(hdrdir)/ruby/internal/intern/bignum.h
-monitor.o: $(hdrdir)/ruby/internal/intern/class.h
-monitor.o: $(hdrdir)/ruby/internal/intern/compar.h
-monitor.o: $(hdrdir)/ruby/internal/intern/complex.h
-monitor.o: $(hdrdir)/ruby/internal/intern/cont.h
-monitor.o: $(hdrdir)/ruby/internal/intern/dir.h
-monitor.o: $(hdrdir)/ruby/internal/intern/enum.h
-monitor.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-monitor.o: $(hdrdir)/ruby/internal/intern/error.h
-monitor.o: $(hdrdir)/ruby/internal/intern/eval.h
-monitor.o: $(hdrdir)/ruby/internal/intern/file.h
-monitor.o: $(hdrdir)/ruby/internal/intern/gc.h
-monitor.o: $(hdrdir)/ruby/internal/intern/hash.h
-monitor.o: $(hdrdir)/ruby/internal/intern/io.h
-monitor.o: $(hdrdir)/ruby/internal/intern/load.h
-monitor.o: $(hdrdir)/ruby/internal/intern/marshal.h
-monitor.o: $(hdrdir)/ruby/internal/intern/numeric.h
-monitor.o: $(hdrdir)/ruby/internal/intern/object.h
-monitor.o: $(hdrdir)/ruby/internal/intern/parse.h
-monitor.o: $(hdrdir)/ruby/internal/intern/proc.h
-monitor.o: $(hdrdir)/ruby/internal/intern/process.h
-monitor.o: $(hdrdir)/ruby/internal/intern/random.h
-monitor.o: $(hdrdir)/ruby/internal/intern/range.h
-monitor.o: $(hdrdir)/ruby/internal/intern/rational.h
-monitor.o: $(hdrdir)/ruby/internal/intern/re.h
-monitor.o: $(hdrdir)/ruby/internal/intern/ruby.h
-monitor.o: $(hdrdir)/ruby/internal/intern/select.h
-monitor.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-monitor.o: $(hdrdir)/ruby/internal/intern/signal.h
-monitor.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-monitor.o: $(hdrdir)/ruby/internal/intern/string.h
-monitor.o: $(hdrdir)/ruby/internal/intern/struct.h
-monitor.o: $(hdrdir)/ruby/internal/intern/thread.h
-monitor.o: $(hdrdir)/ruby/internal/intern/time.h
-monitor.o: $(hdrdir)/ruby/internal/intern/variable.h
-monitor.o: $(hdrdir)/ruby/internal/intern/vm.h
-monitor.o: $(hdrdir)/ruby/internal/interpreter.h
-monitor.o: $(hdrdir)/ruby/internal/iterator.h
-monitor.o: $(hdrdir)/ruby/internal/memory.h
-monitor.o: $(hdrdir)/ruby/internal/method.h
-monitor.o: $(hdrdir)/ruby/internal/module.h
-monitor.o: $(hdrdir)/ruby/internal/newobj.h
-monitor.o: $(hdrdir)/ruby/internal/rgengc.h
-monitor.o: $(hdrdir)/ruby/internal/scan_args.h
-monitor.o: $(hdrdir)/ruby/internal/special_consts.h
-monitor.o: $(hdrdir)/ruby/internal/static_assert.h
-monitor.o: $(hdrdir)/ruby/internal/stdalign.h
-monitor.o: $(hdrdir)/ruby/internal/stdbool.h
-monitor.o: $(hdrdir)/ruby/internal/symbol.h
-monitor.o: $(hdrdir)/ruby/internal/token_paste.h
-monitor.o: $(hdrdir)/ruby/internal/value.h
-monitor.o: $(hdrdir)/ruby/internal/value_type.h
-monitor.o: $(hdrdir)/ruby/internal/variable.h
-monitor.o: $(hdrdir)/ruby/internal/warning_push.h
-monitor.o: $(hdrdir)/ruby/internal/xmalloc.h
-monitor.o: $(hdrdir)/ruby/assert.h
-monitor.o: $(hdrdir)/ruby/backward.h
-monitor.o: $(hdrdir)/ruby/backward/2/assume.h
-monitor.o: $(hdrdir)/ruby/backward/2/attributes.h
-monitor.o: $(hdrdir)/ruby/backward/2/bool.h
-monitor.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-monitor.o: $(hdrdir)/ruby/backward/2/inttypes.h
-monitor.o: $(hdrdir)/ruby/backward/2/limits.h
-monitor.o: $(hdrdir)/ruby/backward/2/long_long.h
-monitor.o: $(hdrdir)/ruby/backward/2/stdalign.h
-monitor.o: $(hdrdir)/ruby/backward/2/stdarg.h
-monitor.o: $(hdrdir)/ruby/defines.h
-monitor.o: $(hdrdir)/ruby/intern.h
-monitor.o: $(hdrdir)/ruby/missing.h
-monitor.o: $(hdrdir)/ruby/ruby.h
-monitor.o: $(hdrdir)/ruby/st.h
-monitor.o: $(hdrdir)/ruby/subst.h
-monitor.o: monitor.c
-# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/monitor/extconf.rb b/ext/monitor/extconf.rb
deleted file mode 100644
index 78c53fa0c5..0000000000
--- a/ext/monitor/extconf.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require 'mkmf'
-create_makefile('monitor')
diff --git a/ext/monitor/lib/monitor.rb b/ext/monitor/lib/monitor.rb
deleted file mode 100644
index 11c5ac17d9..0000000000
--- a/ext/monitor/lib/monitor.rb
+++ /dev/null
@@ -1,284 +0,0 @@
-# frozen_string_literal: false
-# = monitor.rb
-#
-# Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
-#
-# This library is distributed under the terms of the Ruby license.
-# You can freely distribute/modify this library.
-#
-
-#
-# In concurrent programming, a monitor is an object or module intended to be
-# used safely by more than one thread. The defining characteristic of a
-# monitor is that its methods are executed with mutual exclusion. That is, at
-# each point in time, at most one thread may be executing any of its methods.
-# This mutual exclusion greatly simplifies reasoning about the implementation
-# of monitors compared to reasoning about parallel code that updates a data
-# structure.
-#
-# You can read more about the general principles on the Wikipedia page for
-# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
-#
-# == Examples
-#
-# === Simple object.extend
-#
-# require 'monitor.rb'
-#
-# buf = []
-# buf.extend(MonitorMixin)
-# empty_cond = buf.new_cond
-#
-# # consumer
-# Thread.start do
-# loop do
-# buf.synchronize do
-# empty_cond.wait_while { buf.empty? }
-# print buf.shift
-# end
-# end
-# end
-#
-# # producer
-# while line = ARGF.gets
-# buf.synchronize do
-# buf.push(line)
-# empty_cond.signal
-# end
-# end
-#
-# The consumer thread waits for the producer thread to push a line to buf
-# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
-# line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
-# to notify the consumer thread of new data.
-#
-# === Simple Class include
-#
-# require 'monitor'
-#
-# class SynchronizedArray < Array
-#
-# include MonitorMixin
-#
-# def initialize(*args)
-# super(*args)
-# end
-#
-# alias :old_shift :shift
-# alias :old_unshift :unshift
-#
-# def shift(n=1)
-# self.synchronize do
-# self.old_shift(n)
-# end
-# end
-#
-# def unshift(item)
-# self.synchronize do
-# self.old_unshift(item)
-# end
-# end
-#
-# # other methods ...
-# end
-#
-# +SynchronizedArray+ implements an Array with synchronized access to items.
-# This Class is implemented as subclass of Array which includes the
-# MonitorMixin module.
-#
-
-require 'monitor.so'
-
-module MonitorMixin
- #
- # FIXME: This isn't documented in Nutshell.
- #
- # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
- # above calls while_wait and signal, this class should be documented.
- #
- class ConditionVariable
- #
- # Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
- #
- # If +timeout+ is given, this method returns after +timeout+ seconds passed,
- # even if no other thread doesn't signal.
- #
- def wait(timeout = nil)
- @monitor.mon_check_owner
- @monitor.wait_for_cond(@cond, timeout)
- end
-
- #
- # Calls wait repeatedly while the given block yields a truthy value.
- #
- def wait_while
- while yield
- wait
- end
- end
-
- #
- # Calls wait repeatedly until the given block yields a truthy value.
- #
- def wait_until
- until yield
- wait
- end
- end
-
- #
- # Wakes up the first thread in line waiting for this lock.
- #
- def signal
- @monitor.mon_check_owner
- @cond.signal
- end
-
- #
- # Wakes up all threads waiting for this lock.
- #
- def broadcast
- @monitor.mon_check_owner
- @cond.broadcast
- end
-
- private
-
- def initialize(monitor)
- @monitor = monitor
- @cond = Thread::ConditionVariable.new
- end
- end
-
- def self.extend_object(obj)
- super(obj)
- obj.__send__(:mon_initialize)
- end
-
- #
- # Attempts to enter exclusive section. Returns +false+ if lock fails.
- #
- def mon_try_enter
- @mon_data.try_enter
- end
- # For backward compatibility
- alias try_mon_enter mon_try_enter
-
- #
- # Enters exclusive section.
- #
- def mon_enter
- @mon_data.enter
- end
-
- #
- # Leaves exclusive section.
- #
- def mon_exit
- mon_check_owner
- @mon_data.exit
- end
-
- #
- # Returns true if this monitor is locked by any thread
- #
- def mon_locked?
- @mon_data.mon_locked?
- end
-
- #
- # Returns true if this monitor is locked by current thread.
- #
- def mon_owned?
- @mon_data.mon_owned?
- end
-
- #
- # Enters exclusive section and executes the block. Leaves the exclusive
- # section automatically when the block exits. See example under
- # +MonitorMixin+.
- #
- def mon_synchronize(&b)
- @mon_data.synchronize(&b)
- end
- alias synchronize mon_synchronize
-
- #
- # Creates a new MonitorMixin::ConditionVariable associated with the
- # Monitor object.
- #
- def new_cond
- unless defined?(@mon_data)
- mon_initialize
- @mon_initialized_by_new_cond = true
- end
- return ConditionVariable.new(@mon_data)
- end
-
- private
-
- # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead
- # of this constructor. Have look at the examples above to understand how to
- # use this module.
- def initialize(...)
- super
- mon_initialize
- end
-
- # Initializes the MonitorMixin after being included in a class or when an
- # object has been extended with the MonitorMixin
- def mon_initialize
- if defined?(@mon_data)
- if defined?(@mon_initialized_by_new_cond)
- return # already initialized.
- elsif @mon_data_owner_object_id == self.object_id
- raise ThreadError, "already initialized"
- end
- end
- @mon_data = ::Monitor.new
- @mon_data_owner_object_id = self.object_id
- end
-
- def mon_check_owner
- @mon_data.mon_check_owner
- end
-end
-
-# Use the Monitor class when you want to have a lock object for blocks with
-# mutual exclusion.
-#
-# require 'monitor'
-#
-# lock = Monitor.new
-# lock.synchronize do
-# # exclusive access
-# end
-#
-class Monitor
- def new_cond
- ::MonitorMixin::ConditionVariable.new(self)
- end
-
- # for compatibility
- alias try_mon_enter try_enter
- alias mon_try_enter try_enter
- alias mon_enter enter
- alias mon_exit exit
- alias mon_synchronize synchronize
-end
-
-# Documentation comments:
-# - All documentation comes from Nutshell.
-# - MonitorMixin.new_cond appears in the example, but is not documented in
-# Nutshell.
-# - All the internals (internal modules Accessible and Initializable, class
-# ConditionVariable) appear in RDoc. It might be good to hide them, by
-# making them private, or marking them :nodoc:, etc.
-# - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
-# not synchronize.
-# - mon_owner is in Nutshell, but appears as an accessor in a separate module
-# here, so is hard/impossible to RDoc. Some other useful accessors
-# (mon_count and some queue stuff) are also in this module, and don't appear
-# directly in the RDoc output.
-# - in short, it may be worth changing the code layout in this file to make the
-# documentation easier
diff --git a/ext/monitor/monitor.c b/ext/monitor/monitor.c
deleted file mode 100644
index 26a564f4c3..0000000000
--- a/ext/monitor/monitor.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "ruby/ruby.h"
-
-/* Thread::Monitor */
-
-struct rb_monitor {
- long count;
- const VALUE owner;
- const VALUE mutex;
-};
-
-static void
-monitor_mark(void *ptr)
-{
- struct rb_monitor *mc = ptr;
- rb_gc_mark(mc->owner);
- rb_gc_mark(mc->mutex);
-}
-
-static size_t
-monitor_memsize(const void *ptr)
-{
- return sizeof(struct rb_monitor);
-}
-
-static const rb_data_type_t monitor_data_type = {
- "monitor",
- {monitor_mark, RUBY_TYPED_DEFAULT_FREE, monitor_memsize,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
-};
-
-static VALUE
-monitor_alloc(VALUE klass)
-{
- struct rb_monitor *mc;
- VALUE obj;
-
- obj = TypedData_Make_Struct(klass, struct rb_monitor, &monitor_data_type, mc);
- RB_OBJ_WRITE(obj, &mc->mutex, rb_mutex_new());
- RB_OBJ_WRITE(obj, &mc->owner, Qnil);
- mc->count = 0;
-
- return obj;
-}
-
-static struct rb_monitor *
-monitor_ptr(VALUE monitor)
-{
- struct rb_monitor *mc;
- TypedData_Get_Struct(monitor, struct rb_monitor, &monitor_data_type, mc);
- return mc;
-}
-
-static int
-mc_owner_p(struct rb_monitor *mc)
-{
- return mc->owner == rb_thread_current();
-}
-
-static VALUE
-monitor_try_enter(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
-
- if (!mc_owner_p(mc)) {
- if (!rb_mutex_trylock(mc->mutex)) {
- return Qfalse;
- }
- RB_OBJ_WRITE(monitor, &mc->owner, rb_thread_current());
- mc->count = 0;
- }
- mc->count += 1;
- return Qtrue;
-}
-
-static VALUE
-monitor_enter(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
- if (!mc_owner_p(mc)) {
- rb_mutex_lock(mc->mutex);
- RB_OBJ_WRITE(monitor, &mc->owner, rb_thread_current());
- mc->count = 0;
- }
- mc->count++;
- return Qnil;
-}
-
-static VALUE
-monitor_check_owner(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
- if (!mc_owner_p(mc)) {
- rb_raise(rb_eThreadError, "current thread not owner");
- }
- return Qnil;
-}
-
-static VALUE
-monitor_exit(VALUE monitor)
-{
- monitor_check_owner(monitor);
-
- struct rb_monitor *mc = monitor_ptr(monitor);
-
- if (mc->count <= 0) rb_bug("monitor_exit: count:%d\n", (int)mc->count);
- mc->count--;
-
- if (mc->count == 0) {
- RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
- rb_mutex_unlock(mc->mutex);
- }
- return Qnil;
-}
-
-static VALUE
-monitor_locked_p(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
- return rb_mutex_locked_p(mc->mutex);
-}
-
-static VALUE
-monitor_owned_p(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
- return (rb_mutex_locked_p(mc->mutex) && mc_owner_p(mc)) ? Qtrue : Qfalse;
-}
-
-static VALUE
-monitor_exit_for_cond(VALUE monitor)
-{
- struct rb_monitor *mc = monitor_ptr(monitor);
- long cnt = mc->count;
- RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
- mc->count = 0;
- return LONG2NUM(cnt);
-}
-
-struct wait_for_cond_data {
- VALUE monitor;
- VALUE cond;
- VALUE timeout;
- VALUE count;
-};
-
-static VALUE
-monitor_wait_for_cond_body(VALUE v)
-{
- struct wait_for_cond_data *data = (struct wait_for_cond_data *)v;
- struct rb_monitor *mc = monitor_ptr(data->monitor);
- // cond.wait(monitor.mutex, timeout)
- rb_funcall(data->cond, rb_intern("wait"), 2, mc->mutex, data->timeout);
- return Qtrue;
-}
-
-static VALUE
-monitor_enter_for_cond(VALUE v)
-{
- // assert(rb_mutex_owned_p(mc->mutex) == Qtrue)
- // but rb_mutex_owned_p is not exported...
-
- struct wait_for_cond_data *data = (struct wait_for_cond_data *)v;
- struct rb_monitor *mc = monitor_ptr(data->monitor);
- RB_OBJ_WRITE(data->monitor, &mc->owner, rb_thread_current());
- mc->count = NUM2LONG(data->count);
- return Qnil;
-}
-
-static VALUE
-monitor_wait_for_cond(VALUE monitor, VALUE cond, VALUE timeout)
-{
- VALUE count = monitor_exit_for_cond(monitor);
- struct wait_for_cond_data data = {
- monitor,
- cond,
- timeout,
- count,
- };
-
- return rb_ensure(monitor_wait_for_cond_body, (VALUE)&data,
- monitor_enter_for_cond, (VALUE)&data);
-}
-
-static VALUE
-monitor_sync_body(VALUE monitor)
-{
- return rb_yield_values(0);
-}
-
-static VALUE
-monitor_sync_ensure(VALUE monitor)
-{
- return monitor_exit(monitor);
-}
-
-static VALUE
-monitor_synchronize(VALUE monitor)
-{
- monitor_enter(monitor);
- return rb_ensure(monitor_sync_body, monitor, monitor_sync_ensure, monitor);
-}
-
-void
-Init_monitor(void)
-{
-#if HAVE_RB_EXT_RACTOR_SAFE
- rb_ext_ractor_safe(true);
-#endif
-
- VALUE rb_cMonitor = rb_define_class("Monitor", rb_cObject);
- rb_define_alloc_func(rb_cMonitor, monitor_alloc);
-
- rb_define_method(rb_cMonitor, "try_enter", monitor_try_enter, 0);
- rb_define_method(rb_cMonitor, "enter", monitor_enter, 0);
- rb_define_method(rb_cMonitor, "exit", monitor_exit, 0);
- rb_define_method(rb_cMonitor, "synchronize", monitor_synchronize, 0);
-
- /* internal methods for MonitorMixin */
- rb_define_method(rb_cMonitor, "mon_locked?", monitor_locked_p, 0);
- rb_define_method(rb_cMonitor, "mon_check_owner", monitor_check_owner, 0);
- rb_define_method(rb_cMonitor, "mon_owned?", monitor_owned_p, 0);
-
- /* internal methods for MonitorMixin::ConditionVariable */
- rb_define_method(rb_cMonitor, "wait_for_cond", monitor_wait_for_cond, 2);
-}