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; }