fixing flaky tests in mac and windows

This commit is contained in:
matlabbe
2026-05-30 21:28:53 -07:00
parent e8eabc1538
commit 3ecddfb583
6 changed files with 77 additions and 19 deletions
+29 -3
View File
@@ -29,6 +29,7 @@
#ifdef _WIN32
#include "rtabmap/utilite/Win32/UWin32.h"
#include <atomic>
#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
#else
#include <pthread.h>
@@ -59,6 +60,9 @@ public:
* @param n number to initialize
*/
USemaphore( int initValue = 0 )
#ifdef _WIN32
: _count(initValue)
#endif
{
#ifdef _WIN32
S = CreateSemaphore(0,initValue,SEM_VALUE_MAX,0);
@@ -94,6 +98,9 @@ public:
while(n-- > 0 && rt==0)
{
rt = WaitForSingleObject((HANDLE)S, ms<=0?INFINITE:ms);
if(rt == 0) {
--_count;
}
}
return rt == 0;
}
@@ -138,7 +145,15 @@ public:
#ifdef _WIN32
bool acquireTry() const
{
return ((WaitForSingleObject((HANDLE)S,INFINITE)==WAIT_OBJECT_0)?true:false);
// Non-blocking try-acquire: timeout 0, not INFINITE. INFINITE here
// turned this into a blocking acquire and hung tests when the count
// reached 0.
if(WaitForSingleObject((HANDLE)S, 0) == WAIT_OBJECT_0)
{
--_count;
return true;
}
return false;
}
#else
bool acquireTry(int n)
@@ -163,7 +178,12 @@ public:
#ifdef _WIN32
bool release(int n = 1) const
{
return (ReleaseSemaphore((HANDLE)S,n,0)?true:false);
if(ReleaseSemaphore((HANDLE)S, n, 0))
{
_count += n;
return true;
}
return false;
}
#else
bool release(int n = 1)
@@ -183,7 +203,11 @@ public:
#ifdef _WIN32
int value() const
{
LONG V = -1; ReleaseSemaphore((HANDLE)S,0,&V); return V;
// ReleaseSemaphore(S, 0, &V) returns FALSE on Windows (release count
// must be >= 1) and never writes V, so we mirror the count in an atomic
// instead. The value is eventually-consistent under concurrent
// acquire/release but accurate at quiescence.
return (int)_count.load();
}
#else
int value()
@@ -206,6 +230,7 @@ public:
{
CloseHandle(S);
S = CreateSemaphore(0,init,SEM_VALUE_MAX,0);
_count = init;
}
#endif
@@ -214,6 +239,7 @@ private:
#ifdef _WIN32
USemaphore(const USemaphore &S){}
HANDLE S;
mutable std::atomic<long> _count;
#else
USemaphore(const USemaphore &):_available(0){}
pthread_mutex_t _waitMutex;
+19 -3
View File
@@ -460,13 +460,29 @@ TEST(ULoggerTest, ThreadIdFilterVector)
ULogger::registerCurrentThread("FilterThread");
OtherThread otherThread;
otherThread.start();
// OtherThread registers itself from inside mainLoopBegin(), which runs
// asynchronously after start(). setTreadIdFilter() resolves names against
// the current registeredThreads_ map, so we have to wait for the other
// thread to register before applying the filter -- otherwise only
// "FilterThread" ends up in the filter set (intermittent failure on slow
// Windows runners).
for(int i = 0; i < 200; ++i)
{
const std::map<std::string, unsigned long> regs = ULogger::getRegisteredThreads();
if(regs.find(otherThread.name()) != regs.end())
{
break;
}
uSleep(10);
}
std::vector<std::string> threadNames;
threadNames.push_back(otherThread.name());
threadNames.push_back("FilterThread");
ULogger::setTreadIdFilter(threadNames);
const std::set<unsigned long>& retrieved = ULogger::getTreadIdFilter();
EXPECT_EQ(retrieved.size(), 2u);
+2 -1
View File
@@ -116,8 +116,9 @@ TEST(USemaphoreTest, AcquireTry)
result = sem.acquireTry();
EXPECT_TRUE(result);
EXPECT_EQ(sem.value(), 0);
// Semaphore is exhausted: the next non-blocking try must fail.
result = sem.acquireTry();
EXPECT_TRUE(result);
EXPECT_FALSE(result);
#else
int result = sem.acquireTry(1);
EXPECT_TRUE(result);