| 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.
/*
* 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;
}
/*
* 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;
}
Removes all objects from the queue.
/*
* 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;
}
Removes all objects from the queue.
/*
* 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;
}
Returns true if the queue is empty.
/*
* 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;
}
Returns true if the queue is empty.
/*
* 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;
}
Returns the length of the queue.
/*
* 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;
}
Returns the length of the queue.
/*
* 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;
}
Returns the maximum size of the queue.
/*
* 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;
}
Returns the maximum size of the queue.
/*
* 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;
}
Sets the maximum size of the queue.
/*
* 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;
}
Sets the maximum size of the queue.
/*
* 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;
}
Returns the number of threads waiting on the queue.
/*
* 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;
}
Returns the number of threads waiting on the queue.
/*
* 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;
}
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.
/*
* 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;
}
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.
/*
* 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;
}
Pushes obj to the queue.
/*
* 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;
}
Pushes obj to the queue.
/*
* 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;
}