Class: SizedQueue

Class | SizedQueue
In: | ext/fastthread/fastthread.c ext/fastthread/fastthread.c
Parent: | Queue

This class represents queues of specified size capacity. The push operation may be blocked if the capacity is full.

See Queue for an example of how a SizedQueue works.

### Methods

clear clear empty? empty? length length max max max= max= new new num_waiting num_waiting pop pop push push

### Public Class methods

Mutex.new

Creates a new Mutex

[Source]

    /*
     * Document-method: max=
     * call-seq: max=(size)
     *
     * Sets the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max_set(VALUE self, VALUE value)
    {
        Queue *queue;
        unsigned long new_capacity;
        unsigned long difference;
        Data_Get_Struct(self, Queue, queue);

        new_capacity = NUM2ULONG(value);

        if (new_capacity < 1) {
            rb_raise(rb_eArgError, "value must be positive");
        }

        lock_mutex(&queue->mutex);
        if (queue->capacity && new_capacity > queue->capacity) {
            difference = new_capacity - queue->capacity;
        } else {
            difference = 0;
        }
        queue->capacity = new_capacity;
        for (; difference > 0; --difference) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return self;
    }

Mutex.new

Creates a new Mutex

[Source]

    /*
     * Document-method: max=
     * call-seq: max=(size)
     *
     * Sets the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max_set(VALUE self, VALUE value)
    {
        Queue *queue;
        unsigned long new_capacity;
        unsigned long difference;
        Data_Get_Struct(self, Queue, queue);

        new_capacity = NUM2ULONG(value);

        if (new_capacity < 1) {
            rb_raise(rb_eArgError, "value must be positive");
        }

        lock_mutex(&queue->mutex);
        if (queue->capacity && new_capacity > queue->capacity) {
            difference = new_capacity - queue->capacity;
        } else {
            difference = 0;
        }
        queue->capacity = new_capacity;
        for (; difference > 0; --difference) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return self;
    }

### Public Instance methods

clear

Removes all objects from the queue.

[Source]

    /*
     * Document-method: clear
     * call-seq: clear
     *
     * Removes all objects from the queue.
     *
     */

    static VALUE
    rb_queue_clear(VALUE self)
    {
        Queue *queue;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        clear_list(&queue->values);
        signal_condvar(&queue->space_available);
        unlock_mutex(&queue->mutex);

        return self;
    }

clear

Removes all objects from the queue.

[Source]

    /*
     * Document-method: clear
     * call-seq: clear
     *
     * Removes all objects from the queue.
     *
     */

    static VALUE
    rb_queue_clear(VALUE self)
    {
        Queue *queue;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        clear_list(&queue->values);
        signal_condvar(&queue->space_available);
        unlock_mutex(&queue->mutex);

        return self;
    }

empty?

Returns `true` if the queue is empty.

[Source]

    /*
     * Document-method: empty?
     * call-seq: empty?
     *
     * Returns +true+ if the queue is empty.
     *
     */

    static VALUE
    rb_queue_empty_p(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = queue->values.size == 0 ? Qtrue : Qfalse;
        unlock_mutex(&queue->mutex);

        return result;
    }

empty?

Returns `true` if the queue is empty.

[Source]

    /*
     * Document-method: empty?
     * call-seq: empty?
     *
     * Returns +true+ if the queue is empty.
     *
     */

    static VALUE
    rb_queue_empty_p(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = queue->values.size == 0 ? Qtrue : Qfalse;
        unlock_mutex(&queue->mutex);

        return result;
    }

length

Returns the length of the queue.

[Source]

    /*
     * Document-method: length
     * call-seq: length
     *
     * Returns the length of the queue.
     *
     */

    static VALUE
    rb_queue_length(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->values.size);
        unlock_mutex(&queue->mutex);

        return result;
    }

length

Returns the length of the queue.

[Source]

    /*
     * Document-method: length
     * call-seq: length
     *
     * Returns the length of the queue.
     *
     */

    static VALUE
    rb_queue_length(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->values.size);
        unlock_mutex(&queue->mutex);

        return result;
    }

max

Returns the maximum size of the queue.

[Source]

    /*
     * Document-method: max
     * call-seq: max
     *
     * Returns the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->capacity);
        unlock_mutex(&queue->mutex);

        return result;
    }

max

Returns the maximum size of the queue.

[Source]

    /*
     * Document-method: max
     * call-seq: max
     *
     * Returns the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->capacity);
        unlock_mutex(&queue->mutex);

        return result;
    }

max=(size)

Sets the maximum size of the queue.

[Source]

    /*
     * Document-method: max=
     * call-seq: max=(size)
     *
     * Sets the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max_set(VALUE self, VALUE value)
    {
        Queue *queue;
        unsigned long new_capacity;
        unsigned long difference;
        Data_Get_Struct(self, Queue, queue);

        new_capacity = NUM2ULONG(value);

        if (new_capacity < 1) {
            rb_raise(rb_eArgError, "value must be positive");
        }

        lock_mutex(&queue->mutex);
        if (queue->capacity && new_capacity > queue->capacity) {
            difference = new_capacity - queue->capacity;
        } else {
            difference = 0;
        }
        queue->capacity = new_capacity;
        for (; difference > 0; --difference) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return self;
    }

max=(size)

Sets the maximum size of the queue.

[Source]

    /*
     * Document-method: max=
     * call-seq: max=(size)
     *
     * Sets the maximum size of the queue.
     *
     */

    static VALUE
    rb_sized_queue_max_set(VALUE self, VALUE value)
    {
        Queue *queue;
        unsigned long new_capacity;
        unsigned long difference;
        Data_Get_Struct(self, Queue, queue);

        new_capacity = NUM2ULONG(value);

        if (new_capacity < 1) {
            rb_raise(rb_eArgError, "value must be positive");
        }

        lock_mutex(&queue->mutex);
        if (queue->capacity && new_capacity > queue->capacity) {
            difference = new_capacity - queue->capacity;
        } else {
            difference = 0;
        }
        queue->capacity = new_capacity;
        for (; difference > 0; --difference) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return self;
    }

num_waiting

Returns the number of threads waiting on the queue.

[Source]

    /*
     * Document-method: num_waiting
     * call-seq: num_waiting
     *
     * Returns the number of threads waiting on the queue.
     *
     */

    static VALUE
    rb_queue_num_waiting(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->value_available.waiting.size +
          queue->space_available.waiting.size);
        unlock_mutex(&queue->mutex);

        return result;
    }

num_waiting

Returns the number of threads waiting on the queue.

[Source]

    /*
     * Document-method: num_waiting
     * call-seq: num_waiting
     *
     * Returns the number of threads waiting on the queue.
     *
     */

    static VALUE
    rb_queue_num_waiting(VALUE self)
    {
        Queue *queue;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        result = ULONG2NUM(queue->value_available.waiting.size +
          queue->space_available.waiting.size);
        unlock_mutex(&queue->mutex);

        return result;
    }

pop(...)

call_seq: pop(non_block=false)

Retrieves data from the queue. If the queue is empty, the calling thread is suspended until data is pushed onto the queue. If `non_block` is true, the thread isn‘t suspended, and an exception is raised.

[Source]

    /*
     * Document-method: pop
     * call_seq: pop(non_block=false)
     *
     * Retrieves data from the queue.  If the queue is empty, the calling thread is
     * suspended until data is pushed onto the queue.  If +non_block+ is true, the
     * thread isn't suspended, and an exception is raised.
     *
     */

    static VALUE
    rb_queue_pop(int argc, VALUE *argv, VALUE self)
    {
        Queue *queue;
        int should_block;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        if (argc == 0) {
            should_block = 1;
        } else if (argc == 1) {
            should_block = !RTEST(argv[0]);
        } else {
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
        }

        lock_mutex(&queue->mutex);
        if (!queue->values.entries && !should_block) {
            unlock_mutex(&queue->mutex);
            rb_raise(private_eThreadError, "queue empty");
        }

        while (!queue->values.entries) {
            wait_condvar(&queue->value_available, &queue->mutex);
        }

        result = shift_list(&queue->values);
        if (queue->capacity && queue->values.size < queue->capacity) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return result;
    }

pop(...)

call_seq: pop(non_block=false)

Retrieves data from the queue. If the queue is empty, the calling thread is suspended until data is pushed onto the queue. If `non_block` is true, the thread isn‘t suspended, and an exception is raised.

[Source]

    /*
     * Document-method: pop
     * call_seq: pop(non_block=false)
     *
     * Retrieves data from the queue.  If the queue is empty, the calling thread is
     * suspended until data is pushed onto the queue.  If +non_block+ is true, the
     * thread isn't suspended, and an exception is raised.
     *
     */

    static VALUE
    rb_queue_pop(int argc, VALUE *argv, VALUE self)
    {
        Queue *queue;
        int should_block;
        VALUE result;
        Data_Get_Struct(self, Queue, queue);

        if (argc == 0) {
            should_block = 1;
        } else if (argc == 1) {
            should_block = !RTEST(argv[0]);
        } else {
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
        }

        lock_mutex(&queue->mutex);
        if (!queue->values.entries && !should_block) {
            unlock_mutex(&queue->mutex);
            rb_raise(private_eThreadError, "queue empty");
        }

        while (!queue->values.entries) {
            wait_condvar(&queue->value_available, &queue->mutex);
        }

        result = shift_list(&queue->values);
        if (queue->capacity && queue->values.size < queue->capacity) {
            signal_condvar(&queue->space_available);
        }
        unlock_mutex(&queue->mutex);

        return result;
    }

push(obj)

Pushes `obj` to the queue.

[Source]

    /*
     * Document-method: push
     * call-seq: push(obj)
     *
     * Pushes +obj+ to the queue.
     *
     */

    static VALUE
    rb_queue_push(VALUE self, VALUE value)
    {
        Queue *queue;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        while (queue->capacity && queue->values.size >= queue->capacity) {
            wait_condvar(&queue->space_available, &queue->mutex);
        }
        push_list(&queue->values, value);
        signal_condvar(&queue->value_available);
        unlock_mutex(&queue->mutex);

        return self;
    }

push(obj)

Pushes `obj` to the queue.

[Source]

    /*
     * Document-method: push
     * call-seq: push(obj)
     *
     * Pushes +obj+ to the queue.
     *
     */

    static VALUE
    rb_queue_push(VALUE self, VALUE value)
    {
        Queue *queue;
        Data_Get_Struct(self, Queue, queue);

        lock_mutex(&queue->mutex);
        while (queue->capacity && queue->values.size >= queue->capacity) {
            wait_condvar(&queue->space_available, &queue->mutex);
        }
        push_list(&queue->values, value);
        signal_condvar(&queue->value_available);
        unlock_mutex(&queue->mutex);

        return self;
    }

[Validate]