[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 07/07: Fix close-port race.
From: |
Andy Wingo |
Subject: |
[Guile-commits] 07/07: Fix close-port race. |
Date: |
Sun, 8 Jan 2017 14:51:37 +0000 (UTC) |
wingo pushed a commit to branch master
in repository guile.
commit b392d81c9ca0bec82b43ca49e8cf96c0e9460a89
Author: Andy Wingo <address@hidden>
Date: Sun Jan 8 15:42:22 2017 +0100
Fix close-port race.
* libguile/ports.c (release_port): Fix race.
---
libguile/ports.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/libguile/ports.c b/libguile/ports.c
index 20319bc..f415453 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -134,15 +134,22 @@ static void
release_port (SCM port)
{
scm_t_port *pt = SCM_PORT (port);
- scm_t_uint32 prev;
- prev = scm_atomic_subtract_uint32 (&pt->refcount, 1);
- if (prev == 0)
- /* Logic failure. */
- abort ();
-
- if (prev > 1)
- /* Port still alive. */
+ /* It's possible for two close-port invocations to race, and since
+ close-port is defined to be idempotent we need to avoid
+ decrementing the refcount past 0. The normal case is that it's
+ open with a refcount of 1 and we're going to change it to 0.
+ Otherwise if the refcount is higher we just subtract 1 and we're
+ done. However if the current refcount is 0 then the port has been
+ closed or is closing and we just return. */
+ scm_t_uint32 cur = 1, next = 0;
+ while (!scm_atomic_compare_and_swap_uint32 (&pt->refcount, &cur, next))
+ {
+ if (cur == 0)
+ return;
+ next = cur - 1;
+ }
+ if (cur > 1)
return;
/* FIXME: `catch' around the close call? It could throw an exception,
- [Guile-commits] branch master updated (a0656ad -> b392d81), Andy Wingo, 2017/01/08
- [Guile-commits] 02/07: Remove thread-exited? check in sigaction, Andy Wingo, 2017/01/08
- [Guile-commits] 01/07: Thread prepare-to-wait respects block_asyncs, Andy Wingo, 2017/01/08
- [Guile-commits] 03/07: Remove thread-specific admin mutex, Andy Wingo, 2017/01/08
- [Guile-commits] 04/07: Enable interrupts only when running thread body, Andy Wingo, 2017/01/08
- [Guile-commits] 06/07: Exited threads retain less memory, Andy Wingo, 2017/01/08
- [Guile-commits] 05/07: Prevent some interrupts of wait-condition-variable, Andy Wingo, 2017/01/08
- [Guile-commits] 07/07: Fix close-port race.,
Andy Wingo <=