added 1 changeset to branch 'refs/remotes/looncraz-github/CAP-dirty' old head: be405f1302079b492952399a93c76c48a3f1674d new head: 0d8212774ea54be930014973d933c00ea30224d0 overview: https://github.com/looncraz/haiku/compare/be405f130207...0d8212774ea5 ---------------------------------------------------------------------------- 0d8212774ea5: Minor tweaks Prevent CompositeWindow from setting itself to compositing mode for now, Add a client auto-locker for WeakLazyLocker. Fixed a race condition in WeakLazyLocker. Minor update to set state handling [ looncraz <looncraz@xxxxxxxxxxxx> ] ---------------------------------------------------------------------------- Commit: 0d8212774ea54be930014973d933c00ea30224d0 Author: looncraz <looncraz@xxxxxxxxxxxx> Date: Thu Mar 26 06:15:11 2015 UTC ---------------------------------------------------------------------------- 5 files changed, 78 insertions(+), 11 deletions(-) src/servers/app/Desktop.cpp | 5 ++ .../drawing/interface/local/CompositeWindow.cpp | 14 +++--- .../drawing/interface/local/CompositeWindow.h | 2 + .../drawing/interface/local/WeakLazyLocker.cpp | 19 ++++++-- .../app/drawing/interface/local/WeakLazyLocker.h | 49 ++++++++++++++++++++ ---------------------------------------------------------------------------- diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index fd97f0a..4ddde91 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -2695,6 +2695,11 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (error == B_ALREADY_RUNNING) { CAPTRACE("Already running, but no worries ;-)\n"); error = B_OK; + } else if (error != B_OK) { + CAPTRACE("ERROR! Unable to set compositing state!\n"); + fLink.StartMessage(B_ERROR); + fLink.Flush(); + break; } LockSingleWindow(); diff --git a/src/servers/app/drawing/interface/local/CompositeWindow.cpp b/src/servers/app/drawing/interface/local/CompositeWindow.cpp index 9017a6f..4008e3f 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindow.cpp +++ b/src/servers/app/drawing/interface/local/CompositeWindow.cpp @@ -136,10 +136,9 @@ CompositeWindow::ProcessDirtyRegion(BRegion& regionOnScreen) // We don't want to mess with these during the compositer lock //... which only occurs in single-buffered mode - ClientLock(); - fDirtyCopyRegion.Include(&dirtyCopyRegion); - fDirtyAlphaRegion.Include(&dirtyAlphaRegion); - ClientUnlock(); + WLAutoClientLock _(&fLazyLock); + fDirtyCopyRegion.Include(&dirtyCopyRegion); + fDirtyAlphaRegion.Include(&dirtyAlphaRegion); } @@ -281,6 +280,7 @@ CompositeWindow::ClientUnlock() void CompositeWindow::CompositingEnabled(bool enabled) { + CAPTRACEF("%s\n", enabled ? "ENABLED" : "DISABLED"); // the whole Desktop window list is compositing (by default) // ... or not... // Before this is called, we can't assume that to be the case, so this is @@ -296,7 +296,8 @@ CompositeWindow::CompositingEnabled(bool enabled) void CompositeWindow::CompositingEnabling() { - fIsCompositeWindow = true; + CAPTRACE("\n"); + //fIsCompositeWindow = true; // allocate our buffers, set enabled, trigger client redraw } @@ -304,7 +305,8 @@ CompositeWindow::CompositingEnabling() void CompositeWindow::CompositingDisabling() { - fIsCompositeWindow = false; + CAPTRACE("\n"); + //fIsCompositeWindow = false; // delete our buffers, trigger client redraw } diff --git a/src/servers/app/drawing/interface/local/CompositeWindow.h b/src/servers/app/drawing/interface/local/CompositeWindow.h index 9a9e593..2d85141 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindow.h +++ b/src/servers/app/drawing/interface/local/CompositeWindow.h @@ -101,4 +101,6 @@ private: WeakLazyLocker fLazyLock; }; + + #endif // CAP_COMPOSITE_WINDOW_H diff --git a/src/servers/app/drawing/interface/local/WeakLazyLocker.cpp b/src/servers/app/drawing/interface/local/WeakLazyLocker.cpp index 2ec7485..a974a68 100644 --- a/src/servers/app/drawing/interface/local/WeakLazyLocker.cpp +++ b/src/servers/app/drawing/interface/local/WeakLazyLocker.cpp @@ -69,13 +69,16 @@ WeakLazyLocker::UnsetLazyServerLock() bool WeakLazyLocker::ServerLock(bigtime_t timeout) { + if (fServerLock) + return true; + fServerLazyLock = true; if (fLock.LockWithTimeout(timeout) == B_OK) fServerLock = true; fServerLazyLock = false; - return IsServerLocked(); + return fServerLock; } @@ -93,11 +96,17 @@ WeakLazyLocker::ClientLock(bigtime_t timeout) { bigtime_t start = system_time(); - while (fServerLazyLock - && system_time() - start < timeout) - snooze(250); - if (fServerLazyLock) + bool timedOut = false; + while (fServerLazyLock) { + snooze(500); + if (system_time() - start > timeout) { + timedOut = true; + break; + } + } + + if (timedOut) return false; if (fLock.LockWithTimeout(timeout - (system_time() - start)) == B_OK) diff --git a/src/servers/app/drawing/interface/local/WeakLazyLocker.h b/src/servers/app/drawing/interface/local/WeakLazyLocker.h index cb8db77..eaa630e 100644 --- a/src/servers/app/drawing/interface/local/WeakLazyLocker.h +++ b/src/servers/app/drawing/interface/local/WeakLazyLocker.h @@ -17,6 +17,23 @@ This enables CompositeWindow and WindowBuffer to be lazily prepared for interacting with the CompositeEngine with a very low risk of stalling the CompositeEngine. + + TODO: find way to avoid use of BLocker + Our specific usage pattern (and general safety regarding accessing + memory concurrently) means that the occassional improper lock + acquisition will not be a problem, but then we run the risk of + corrupting our state. + + There are x86 instructions (assembly) and c++11 atomics that would be + safe, but we would limit compositing to those platforms, and this would + be a really bad reason to do so. + + See, the ServerLock should be *really* fast. We don't want to stall + even for the default 50us if we don't need to (especially if we fail + to get the lock!). + + To minimize this, of course, we have a "lazy" lock, which prevents + any more client locks. */ @@ -48,6 +65,38 @@ private: }; +class WLAutoClientLock { + WeakLazyLocker* fLock; + bool fLocked; +public: + WLAutoClientLock(WeakLazyLocker* lock) + : + fLock(lock), + fLocked(true) + { + fLock->ClientLock(); + } + + ~WLAutoClientLock() + { + if (fLocked) + fLock->ClientUnlock(); + } + + bool IsLocked() const + { + return fLocked; + } + + + void Unlock() + { + if (fLocked) { + fLocked = false; + fLock->ClientUnlock(); + } + } +}; #endif // CAP_WEAK_LAZY_LOCKER_H