BPathMonitor: use pthread_once for initialization
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user