summaryrefslogtreecommitdiff
path: root/thread_sync.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2022-10-06 15:53:16 +0200
committerJean Boussier <jean.boussier@gmail.com>2022-10-17 16:56:00 +0200
commit60defe0a68a40d1b3225cf6b971ea195e19ae2e2 (patch)
tree65072a9531c7eb9abfa887a1ad0c18bd4242502d /thread_sync.c
parent7db29de008bbf06ce1dc2a1e9fd9c9684b31e325 (diff)
downloadruby-60defe0a68a40d1b3225cf6b971ea195e19ae2e2.tar.gz
thread_sync.c: Clarify and document the behavior of timeout == 0
[Feature #18982] Instead of introducing an `exception: false` argument to have `non_block` return nil rather than raise, we can clearly document that a timeout of 0 immediately returns. The code is refactored a bit to avoid doing a time calculation in such case.
Diffstat (limited to 'thread_sync.c')
-rw-r--r--thread_sync.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/thread_sync.c b/thread_sync.c
index 4ae404ec05..b2ee052aa5 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -1029,13 +1029,19 @@ static VALUE
queue_do_pop(VALUE self, struct rb_queue *q, int should_block, VALUE timeout)
{
check_array(self, q->que);
- rb_hrtime_t end = queue_timeout2hrtime(timeout);
+ if (RARRAY_LEN(q->que) == 0) {
+ if (!should_block) {
+ rb_raise(rb_eThreadError, "queue empty");
+ }
+
+ if (RTEST(rb_equal(INT2FIX(0), timeout))) {
+ return Qnil;
+ }
+ }
+ rb_hrtime_t end = queue_timeout2hrtime(timeout);
while (RARRAY_LEN(q->que) == 0) {
- if (!should_block) {
- rb_raise(rb_eThreadError, "queue empty");
- }
- else if (queue_closed_p(self)) {
+ if (queue_closed_p(self)) {
return queue_closed_result(self, q);
}
else {
@@ -1232,16 +1238,22 @@ rb_szqueue_max_set(VALUE self, VALUE vmax)
static VALUE
rb_szqueue_push(rb_execution_context_t *ec, VALUE self, VALUE object, VALUE non_block, VALUE timeout)
{
- rb_hrtime_t end = queue_timeout2hrtime(timeout);
- bool timed_out = false;
struct rb_szqueue *sq = szqueue_ptr(self);
+ if (queue_length(self, &sq->q) >= sq->max) {
+ if (RTEST(non_block)) {
+ rb_raise(rb_eThreadError, "queue full");
+ }
+
+ if (RTEST(rb_equal(INT2FIX(0), timeout))) {
+ return Qnil;
+ }
+ }
+
+ rb_hrtime_t end = queue_timeout2hrtime(timeout);
while (queue_length(self, &sq->q) >= sq->max) {
- if (RTEST(non_block)) {
- rb_raise(rb_eThreadError, "queue full");
- }
- else if (queue_closed_p(self)) {
- break;
+ if (queue_closed_p(self)) {
+ raise_closed_queue_error(self);
}
else {
rb_execution_context_t *ec = GET_EC();
@@ -1262,18 +1274,11 @@ rb_szqueue_push(rb_execution_context_t *ec, VALUE self, VALUE object, VALUE non_
};
rb_ensure(queue_sleep, (VALUE)&queue_sleep_arg, szqueue_sleep_done, (VALUE)&queue_waiter);
if (!NIL_P(timeout) && rb_hrtime_now() >= end) {
- timed_out = true;
- break;
+ return Qnil;
}
}
}
- if (queue_closed_p(self)) {
- raise_closed_queue_error(self);
- }
-
- if (timed_out) return Qnil;
-
return queue_do_push(self, &sq->q, object);
}