DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 62GLeDBO405752 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 62GLeDBO405752 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=WYrYxGBd X-Recipient: archive-cygwin AT delorie DOT com DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4CBF04B3588A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com; s=default; t=1773697211; bh=uapuqFa8Qac167mSp7TRCTuvDbe8ubNOAgHLIymrB9k=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=WYrYxGBdZhwcr6OmOXqKs595atbF9Zgc5cJJxV75KLSGJmR4plbdAL98OOf87fZnM JuTRYVvoNOJhFQ3qhh8klPmTsi6dzXkTVKpW8YR+kEkX7z8QYIzixLKRxAL40yM8nC 2ht3OjaKdeC0JD4Bvh1boWqljJmYTGIG89EM1a3M= X-Original-To: cygwin AT cygwin DOT com Delivered-To: cygwin AT cygwin DOT com DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1BF974BB590F ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1BF974BB590F ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773697192; cv=none; b=HnM6hojUJuojy2pKCyrwiUimLNZx4cDcfYWPGVLPMPv31bvOfBxOXmczgb4ck0Kd3sSn2HEfFUosM3M/uh8LA3b42oV4xCeG71upFEmliqGbCahDEKSnqoRnK3bAkKe1+QzNY1JOO0pP+iNMb6rAVwcheuagN+w7Fyk0p+uFB6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773697192; c=relaxed/simple; bh=OP9zMVKJjT77A6NiHPrIxNanFZPW3UbciuBt0FZhzqA=; h=DKIM-Signature:Message-ID:Date:MIME-Version:To:From:Subject; b=q07gQwvBLB05UZzHZMjGFO3gOGG4ON6uVD1/4OtfoM8IF2V3O2IIhS/IZtC24sj1iYSYuHLVXZlweKwCsdBxzNKYh/xojaHobUG9cSRMhnT3Sg6fTYiKsGZIQ5iqsoL8iicXNTjgG21V19LNY8Jt2KEGmEkvx+kLNvF4NbKGRRc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1BF974BB590F X-Authority-Analysis: v=2.4 cv=GOQOEPNK c=1 sm=1 tr=0 ts=69b878a6 a=tvGeiqD8dHAUmuMhmqxQtA==:117 a=tvGeiqD8dHAUmuMhmqxQtA==:17 a=IkcTkHD0fZMA:10 a=ZB0J_u4zfjG5_rlSsLEA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 Message-ID: <2d48a740-ce2b-4259-8947-f5c875dd1672@hvc.rr.com> Date: Mon, 16 Mar 2026 17:39:49 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Cygin Mailing List Subject: std::mutex bug: Windows handle growth X-CMAE-Envelope: MS4xfHVuYx73kTowdagiVarjOko4A764pHLsQMfq0eUHYkPzxVCFccJLvAtg5jK2fc5V0igLMeZZFmDHWjsSsOagIO7yD5b0R65X1FtuBEmscRsNAsq/ky1A DN8Hno9V5G0dFePgD50bk1fum5enMq7ABVDFEhfzslWRkha2DuHyveSJkr0Xsh+WIRrWjF49JBElZQ== X-BeenThere: cygwin AT cygwin DOT com X-Mailman-Version: 2.1.30 List-Id: General Cygwin discussions and problem reports List-Archive: List-Post: List-Help: List-Subscribe: , From: Frank Eskesen via Cygwin Reply-To: Frank Eskesen Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "Cygwin" Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 62GLeDBO405752 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. When commenting out the lock_guard statement, there is no handle growth. When changing the lock_guard to mutex.lock(), the handle growth increases until an exception is thrown. Surprisingly, when changing the lock_guard to mutex.unlock() handle growth increases to about 16,880,000 and doesn't increase more. No exception occurs. (mutex::unlock without mutex::lock is apparently allowed.) The "Invalid argument" exception is presumably thrown somewhere in the mutex locking code. Console output: /home/*******/obj/cpp/Test: Test_mutex FAILED: Exception: exception(Invalid argument) //---------------------------------------------------------------------------- // // Title- //       Test_mutex.cpp // // Purpose- //       Mutex stress test. // // Last change date- //       2026/03/16 // //---------------------------------------------------------------------------- #include                 // For std::exception #include                     // For std::mutex #include                    // For printf #include                     // For timespec, clock_gettime //---------------------------------------------------------------------------- // Constants for parameterization //---------------------------------------------------------------------------- static double          opt_runtime= 60.0; // --runtime option //---------------------------------------------------------------------------- // // Subroutine- //       now // // Purpose- //       Return the number of seconds since the PC epoch. // //---------------------------------------------------------------------------- static double                       // Seconds since the PC epoch    now( void )                      // Get the current time {    struct timespec     ticker;      // UTC time base    clock_gettime(CLOCK_REALTIME, &ticker); //    double seconds= (double)ticker.tv_sec;    seconds += (double)ticker.tv_nsec / 1000000000.0;    return seconds; } //---------------------------------------------------------------------------- // // Subroutine- //       do_something // // Purpose- //       Do something that causes CYGWIN handle growth // //---------------------------------------------------------------------------- static void    do_something(void)               // Try to cause CYGWIN handle growth {    std::mutex mutex;    std::lock_guard lock(mutex); } //---------------------------------------------------------------------------- // // Subroutine- //       test_mutex // // Purpose- //       std::mutex stress test. // //---------------------------------------------------------------------------- static inline void    test_mutex( void )               // Timing test {    double then= now();              // Running timer    while( (now() - then) < opt_runtime )      do_something(); } //---------------------------------------------------------------------------- // // Subroutine- //       main // // Purpose- //       Mainline code. // //---------------------------------------------------------------------------- extern int    main(int, char**)                // Mainline code {    try {      test_mutex();    } catch(std::exception& x) {      printf("FAILED: Exception: exception(%s)\n", x.what());    } catch(...) {      printf("FAILED: Exception: ...\n");    }    return 0; } -- 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