diff --git a/headers/private/interface/ToolTipManager.h b/headers/private/interface/ToolTipManager.h index 604c6c9a6c..190d6ab1a3 100644 --- a/headers/private/interface/ToolTipManager.h +++ b/headers/private/interface/ToolTipManager.h @@ -26,19 +26,22 @@ public: void SetHideDelay(bigtime_t time); bigtime_t HideDelay() const; - static bool Lock() { return sLock.Lock(); } - static void Unlock() { sLock.Unlock(); } + bool Lock() { return fLock.Lock(); } + void Unlock() { fLock.Unlock(); } private: BToolTipManager(); virtual ~BToolTipManager(); + static void _InitSingleton(); + +private: + BLocker fLock; BMessenger fWindow; bigtime_t fShowDelay; bigtime_t fHideDelay; - static BLocker sLock; static BToolTipManager* sDefaultInstance; }; diff --git a/src/kits/interface/ToolTip.cpp b/src/kits/interface/ToolTip.cpp index e68748c2e8..21db081c99 100644 --- a/src/kits/interface/ToolTip.cpp +++ b/src/kits/interface/ToolTip.cpp @@ -110,10 +110,11 @@ BToolTip::Lock() while (true) { lockedLooper = View()->LockLooper(); if (!lockedLooper) { - BToolTipManager::Lock(); + BToolTipManager* manager = BToolTipManager::Manager(); + manager->Lock(); if (View()->Window() != NULL) { - BToolTipManager::Unlock(); + manager->Unlock(); continue; } } @@ -131,7 +132,7 @@ BToolTip::Unlock() if (fLockedLooper) View()->UnlockLooper(); else - BToolTipManager::Unlock(); + BToolTipManager::Manager()->Unlock(); } diff --git a/src/kits/interface/ToolTipManager.cpp b/src/kits/interface/ToolTipManager.cpp index 46fa45d87b..0218069d0c 100644 --- a/src/kits/interface/ToolTipManager.cpp +++ b/src/kits/interface/ToolTipManager.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include @@ -17,7 +19,7 @@ #include -BLocker BToolTipManager::sLock("tool tip manager"); +static pthread_once_t sManagerInitOnce = PTHREAD_ONCE_INIT; BToolTipManager* BToolTipManager::sDefaultInstance; static const uint32 kMsgHideToolTip = 'hide'; @@ -59,13 +61,14 @@ public: virtual void DetachedFromWindow() { - BToolTipManager::Lock(); + BToolTipManager* manager = BToolTipManager::Manager(); + manager->Lock(); RemoveChild(fToolTip->View()); // don't delete this one! fToolTip->DetachedFromWindow(); - BToolTipManager::Unlock(); + manager->Unlock(); } virtual void MouseMoved(BPoint where, uint32 transit, @@ -117,9 +120,10 @@ ToolTipWindow::ToolTipWindow(BToolTip* tip, BPoint where) { SetLayout(new BGroupLayout(B_VERTICAL)); - BToolTipManager::Lock(); + BToolTipManager* manager = BToolTipManager::Manager(); + manager->Lock(); AddChild(new ToolTipView(tip)); - BToolTipManager::Unlock(); + manager->Unlock(); BSize size = ChildAt(0)->PreferredSize(); ResizeTo(size.width, size.height); @@ -194,15 +198,23 @@ ToolTipWindow::MessageReceived(BMessage* message) /*static*/ BToolTipManager* BToolTipManager::Manager() { - BAutolock _(sLock); - + // Note: The check is not necessary; it's just faster than always calling + // pthread_once(). It requires reading/writing of pointers to be atomic + // on the architecture. if (sDefaultInstance == NULL) - sDefaultInstance = new BToolTipManager(); + pthread_once(&sManagerInitOnce, &_InitSingleton); return sDefaultInstance; } +/*static*/ void +BToolTipManager::_InitSingleton() +{ + sDefaultInstance = new BToolTipManager(); +} + + void BToolTipManager::ShowTip(BToolTip* tip, BPoint point) { @@ -282,6 +294,7 @@ BToolTipManager::HideDelay() const BToolTipManager::BToolTipManager() : + fLock("tool tip manager"), fShowDelay(750000), fHideDelay(50000) {