summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler.h')
-rw-r--r--winsup/cygwin/fhandler.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 18e829aa6..84f6e4c3f 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -185,7 +185,11 @@ class fhandler_base
long refcnt(long i = 0)
{
debug_only_printf ("%p, %s, i %d, refcnt %ld", this, get_name (), i, _refcnt + i);
- return _refcnt += i;
+ /* This MUST be an interlocked operation. If multiple threads access the
+ same descriptor in quick succession, a context switch can interrupt
+ the += operation and we wrongly end up with a refcnt of 0 in the
+ cygheap_fdget destructor. */
+ return i ? InterlockedAdd (&_refcnt, i) : _refcnt;
}
class fhandler_base *archetype;
int usecount;