pthread_cond, futex(2) & ECANCELED

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

pthread_cond, futex(2) & ECANCELED

Martin Pieuchot
When futex(2) got imported it didn't return ECANCELED.  This was changed
later with futex-based semaphores.

This modification introduced a behavior change in pthread_cond_*wait(3).
The diff below restores the previous behavior by treating ECANCELED like
EINTR.

Note that the __thrsleep(2) version also doesn't completely check for
ECANCELED, this diff also changes that.

Ok?

Index: rthread_cond.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_cond.c,v
retrieving revision 1.5
diff -u -p -r1.5 rthread_cond.c
--- rthread_cond.c 29 Jan 2019 17:40:26 -0000 1.5
+++ rthread_cond.c 18 Jan 2020 13:10:56 -0000
@@ -109,13 +109,13 @@ _rthread_cond_timedwait(pthread_cond_t c
  * we should just go back to sleep without changing state
  * (timeouts, etc).
  */
- } while ((error == EINTR) &&
+ } while ((error == EINTR || error == ECANCELED) &&
    (tib->tib_canceled == 0 || (tib->tib_cantcancel & CANCEL_DISABLED)));
 
  /* if timeout or canceled, make note of that */
  if (error == ETIMEDOUT)
  rv = ETIMEDOUT;
- else if (error == EINTR)
+ else if (error == EINTR || error == ECANCELED)
  canceled = 1;
 
  pthread_mutex_lock(mutexp);
Index: rthread_sync.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_sync.c,v
retrieving revision 1.5
diff -u -p -r1.5 rthread_sync.c
--- rthread_sync.c 24 Apr 2018 16:28:42 -0000 1.5
+++ rthread_sync.c 18 Jan 2020 13:15:01 -0000
@@ -407,7 +407,7 @@ pthread_cond_timedwait(pthread_cond_t *c
  /* if timeout or canceled, make note of that */
  if (error == EWOULDBLOCK)
  rv = ETIMEDOUT;
- else if (error == EINTR)
+ else if (error == EINTR || error = ECANCELED)
  canceled = 1;
 
  /* transfer between the queues */

Reply | Threaded
Open this post in threaded view
|

Re: pthread_cond, futex(2) & ECANCELED

Martin Pieuchot
On 18/01/20(Sat) 14:16, Martin Pieuchot wrote:
> When futex(2) got imported it didn't return ECANCELED.  This was changed
> later with futex-based semaphores.
>
> This modification introduced a behavior change in pthread_cond_*wait(3).
> The diff below restores the previous behavior by treating ECANCELED like
> EINTR.
>
> Note that the __thrsleep(2) version also doesn't completely check for
> ECANCELED, this diff also changes that.

Updated version below includes a check missed previously in the
__thrsleep(2) based implementation, pointed out by visa@

Index: thread/rthread_cond.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_cond.c,v
retrieving revision 1.5
diff -u -p -r1.5 rthread_cond.c
--- thread/rthread_cond.c 29 Jan 2019 17:40:26 -0000 1.5
+++ thread/rthread_cond.c 18 Jan 2020 13:10:56 -0000
@@ -109,13 +109,13 @@ _rthread_cond_timedwait(pthread_cond_t c
  * we should just go back to sleep without changing state
  * (timeouts, etc).
  */
- } while ((error == EINTR) &&
+ } while ((error == EINTR || error == ECANCELED) &&
    (tib->tib_canceled == 0 || (tib->tib_cantcancel & CANCEL_DISABLED)));
 
  /* if timeout or canceled, make note of that */
  if (error == ETIMEDOUT)
  rv = ETIMEDOUT;
- else if (error == EINTR)
+ else if (error == EINTR || error == ECANCELED)
  canceled = 1;
 
  pthread_mutex_lock(mutexp);
Index: thread/rthread_sync.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_sync.c,v
retrieving revision 1.5
diff -u -p -r1.5 rthread_sync.c
--- thread/rthread_sync.c 24 Apr 2018 16:28:42 -0000 1.5
+++ thread/rthread_sync.c 19 Jan 2020 09:50:06 -0000
@@ -407,7 +407,7 @@ pthread_cond_timedwait(pthread_cond_t *c
  /* if timeout or canceled, make note of that */
  if (error == EWOULDBLOCK)
  rv = ETIMEDOUT;
- else if (error == EINTR)
+ else if (error == EINTR || error = ECANCELED)
  canceled = 1;
 
  /* transfer between the queues */
@@ -544,7 +544,7 @@ pthread_cond_wait(pthread_cond_t *condp,
  assert(self->blocking_cond == cond);
 
  /* if canceled, make note of that */
- if (error == EINTR)
+ if (error == EINTR || error == ECANCELED)
  canceled = 1;
 
  /* transfer between the queues */