delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2026/03/17/15:10:44

DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 62HJAhFE1246576
Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com
Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com
DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 62HJAhFE1246576
Authentication-Results: delorie.com;
dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=S8RrZuhZ
X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0DA2C4BBCDEE
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1773774643;
bh=tSLQ9hRE0jUUzBMPUlx1WDV7MATfL+QYwHCxoCIZl08=;
h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe:
List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:
From;
b=S8RrZuhZQS1gH36lcTwXY8MLqE+t71FosJKLEG+58t304uF6diGbyZ9xuFV0XSK0A
SvAbrMwC2ebQ+qEZ+oQRHylZerSsgBOdKSxnYKh/8fMTpS6JKdlnK9kZuDe2AZI4xM
3nOhRUXGWy3v/n2/28g/kIR4kXfnhQk/ExGRh96A=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7EF744BA23F1
Date: Tue, 17 Mar 2026 20:09:53 +0100
To: ASSI <Stromeko AT nexgo DOT de>
Subject: Re: std::mutex bug: Windows handle growth
Message-ID: <abmnASrGinx_OnuY@calimero.vinschen.de>
Mail-Followup-To: ASSI <Stromeko AT nexgo DOT de>, cygwin AT cygwin DOT com
References: <2d48a740-ce2b-4259-8947-f5c875dd1672 AT hvc DOT rr DOT com> <87tsue4ao5.fsf@>
MIME-Version: 1.0
In-Reply-To: <87tsue4ao5.fsf@>
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Unsubscribe: <https://cygwin.com/mailman/options/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=unsubscribe>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: Corinna Vinschen via Cygwin <cygwin AT cygwin DOT com>
Reply-To: cygwin AT cygwin DOT com
Cc: Corinna Vinschen <corinna-cygwin AT cygwin DOT com>, cygwin AT cygwin DOT com
Errors-To: cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com
Sender: "Cygwin" <cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com>
Note-from-DJ: This may be spam

On Mar 17 18:40, ASSI via Cygwin wrote:
> Frank Eskesen via Cygwin writes:
> > I've run into a problem that occurs on Cygwin that doesn't occur on
> > Linux systems: When a std::mutex is used, it doesn't clean up a
> > Windows handle that it uses. This sample program demonstrates the
> > problem, failing in under 60 seconds. Run this while using Window task
> > manager to watch the handle count rise. On my machine, the count
> > rapidly grows to about 16 million and then a std::exception is thrown.
> 
> This is likely a bug in upstream libstadc++, more specifically by making
> a wrong assumption about the behaviour of the pthread library.  It looks
> like Corinna has identified a potential workaround, but that is a bit
> hack-ish and I'd rather not carry such a patch that will likely not get
> accepted upstream.
> 
> Can you please report this bug upstream and send the link to the
> bugreport here?  Meanwhile, I'd be interested to know if maybe that was
> already fixed in a later version of gcc / libstdc++, so if you could try
> one (or all) of the gcc test versions on your code that would be
> helpful.

My assumption is more or less correct, I was just looking cross-eyed
into the class definition for a while.  Here's the code in question from
bits/std_mutex.h:

--- SNIP ---

  class __mutex_base
  {
  protected:
    typedef __gthread_mutex_t                   __native_type;

#ifdef __GTHREAD_MUTEX_INIT
    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;

    constexpr __mutex_base() noexcept = default;
#else
    __native_type  _M_mutex;

    __mutex_base() noexcept
    {
      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
    }

    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
#endif

    __mutex_base(const __mutex_base&) = delete;
    __mutex_base& operator=(const __mutex_base&) = delete;
  };

--- SNAP ---

The actual problem here is the `#ifdef __GTHREAD_MUTEX_INIT'.

__GTHREAD_MUTEX_INIT translates into PTHREAD_MUTEX_INIT.  If this is
defined, you will notice the there's *no* destructor defined for class
__mutex_base.  Apparently the assumption is made that the underlying
pthread_mutex_t type is a trivial type which doesn't need a destroy(),
if PTHREAD_MUTEX_INIT exists.

However, this is wrong for Cygwin.  It defines PTHREAD_MUTEX_INIT, but
it still needs a pthread_mutex_destroy() call, because the pthread_mutex_t
type is not a trivial one.

Thus, we need a destructor even if __GTHREAD_MUTEX_INIT is defined.

A potential fix would be 

diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h
index 7ef33fe5d0d7..f060c75abf21 100644
--- a/libstdc++-v3/include/bits/std_mutex.h
+++ b/libstdc++-v3/include/bits/std_mutex.h
@@ -68,6 +68,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
 
     constexpr __mutex_base() noexcept = default;
+#ifdef __CYGWIN__
+    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
+#endif
 #else
     __native_type  _M_mutex;

@Stromeko, can you please discuss this upstream?
 

Thanks,
Corinna

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019