Class: Thread::ConditionVariable

Inherits:
Object
  • Object
show all
Defined in:
thread_sync.c,
thread_sync.c

Overview

ConditionVariable objects augment class Mutex. Using condition variables, it is possible to suspend while in the middle of a critical section until a resource becomes available.

Example:

mutex = Thread::Mutex.new
resource = Thread::ConditionVariable.new

a = Thread.new {

mutex.synchronize

# Thread 'a' now needs the resource
resource.wait(mutex)
# 'a' can now have the resource

}

b = Thread.new {

mutex.synchronize

# Thread 'b' has finished using the resource
resource.signal

}

Instance Method Summary collapse

Constructor Details

#initializeObject

Creates a new condition variable instance.


1503
1504
1505
1506
1507
1508
1509
# File 'thread_sync.c', line 1503

static VALUE
rb_condvar_initialize(VALUE self)
{
    struct rb_condvar *cv = condvar_ptr(self);
    ccan_list_head_init(&cv->waitq);
    return self;
}

Instance Method Details

#broadcastObject

Wakes up all threads waiting for this lock.


1577
1578
1579
1580
1581
1582
1583
# File 'thread_sync.c', line 1577

static VALUE
rb_condvar_broadcast(VALUE self)
{
    struct rb_condvar *cv = condvar_ptr(self);
    wakeup_all(&cv->waitq);
    return self;
}

#marshal_dumpObject

:nodoc:


1587
1588
1589
1590
1591
1592
# File 'thread_sync.c', line 1587

static VALUE
undumpable(VALUE obj)
{
    rb_raise(rb_eTypeError, "can't dump %"PRIsVALUE, rb_obj_class(obj));
    UNREACHABLE_RETURN(Qnil);
}

#signalObject

Wakes up the first thread in line waiting for this lock.


1563
1564
1565
1566
1567
1568
1569
# File 'thread_sync.c', line 1563

static VALUE
rb_condvar_signal(VALUE self)
{
    struct rb_condvar *cv = condvar_ptr(self);
    wakeup_one(&cv->waitq);
    return self;
}

#wait(mutex, timeout = nil) ⇒ Object

Releases the lock held in mutex 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.

Returns the slept result on mutex.


1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
# File 'thread_sync.c', line 1537

static VALUE
rb_condvar_wait(int argc, VALUE *argv, VALUE self)
{
    rb_execution_context_t *ec = GET_EC();

    struct rb_condvar *cv = condvar_ptr(self);
    struct sleep_call args;

    rb_scan_args(argc, argv, "11", &args.mutex, &args.timeout);

    struct sync_waiter sync_waiter = {
        .self = args.mutex,
        .th = ec->thread_ptr,
        .fiber = nonblocking_fiber(ec->fiber_ptr)
    };

    ccan_list_add_tail(&cv->waitq, &sync_waiter.node);
    return rb_ensure(do_sleep, (VALUE)&args, delete_from_waitq, (VALUE)&sync_waiter);
}