BPathMonitor: use pthread_once for initialization

This commit is contained in:
Ingo Weinhold
2013-06-27 21:57:40 +02:00
parent 6ca95bd813
commit ad1875fd70
2 changed files with 22 additions and 44 deletions
+2 -2
View File
@@ -33,8 +33,8 @@ private:
BPathMonitor(); BPathMonitor();
~BPathMonitor(); ~BPathMonitor();
static status_t _InitLockerIfNeeded(); static status_t _InitIfNeeded();
static status_t _InitLooperIfNeeded(); static void _Init();
}; };
} // namespace BPrivate } // namespace BPrivate
+19 -41
View File
@@ -143,6 +143,7 @@ class PathHandler : public BHandler {
}; };
static pthread_once_t sInitOnce = PTHREAD_ONCE_INIT;
static WatcherMap sWatchers; static WatcherMap sWatchers;
static BLocker* sLocker = NULL; static BLocker* sLocker = NULL;
static BLooper* sLooper = NULL; static BLooper* sLooper = NULL;
@@ -975,50 +976,32 @@ BPathMonitor::~BPathMonitor()
/*static*/ status_t /*static*/ status_t
BPathMonitor::_InitLockerIfNeeded() BPathMonitor::_InitIfNeeded()
{ {
static vint32 lock = 0; pthread_once(&sInitOnce, &BPathMonitor::_Init);
return sLooper != NULL ? B_OK : B_NO_MEMORY;
if (sLocker != NULL)
return B_OK;
while (sLocker == NULL) {
if (atomic_add(&lock, 1) == 0) {
sLocker = new (nothrow) BLocker("path monitor");
TRACE("Create PathMonitor locker\n");
if (sLocker == NULL)
return B_NO_MEMORY;
}
snooze(5000);
}
return B_OK;
} }
/*static*/ status_t /*static*/ void
BPathMonitor::_InitLooperIfNeeded() BPathMonitor::_Init()
{ {
static vint32 lock = 0; sLocker = new (nothrow) BLocker("path monitor");
TRACE("Create PathMonitor locker\n");
if (sLocker == NULL)
return;
if (sLooper != NULL) BLooper* looper = new (nothrow) BLooper("PathMonitor looper");
return B_OK;
while (sLooper == NULL) {
if (atomic_add(&lock, 1) == 0) {
// first thread initializes the global looper
sLooper = new (nothrow) BLooper("PathMonitor looper");
TRACE("Start PathMonitor looper\n"); TRACE("Start PathMonitor looper\n");
if (sLooper == NULL) if (looper == NULL)
return B_NO_MEMORY; return;
thread_id thread = sLooper->Run(); thread_id thread = looper->Run();
if (thread < B_OK) if (thread < 0) {
return (status_t)thread; delete looper;
} return;
snooze(5000);
} }
return sLooper->Thread() >= 0 ? B_OK : B_ERROR; sLooper = looper;
} }
@@ -1027,15 +1010,10 @@ BPathMonitor::StartWatching(const char* path, uint32 flags, BMessenger target)
{ {
TRACE("StartWatching(%s)\n", path); TRACE("StartWatching(%s)\n", path);
status_t status = _InitLockerIfNeeded(); status_t status = _InitIfNeeded();
if (status != B_OK) if (status != B_OK)
return status; return status;
// use the global looper for receiving node monitor notifications
status = _InitLooperIfNeeded();
if (status < B_OK)
return status;
BAutolock _(sLocker); BAutolock _(sLocker);
WatcherMap::iterator iterator = sWatchers.find(target); WatcherMap::iterator iterator = sWatchers.find(target);