Screen Saver: fix race condition

Start the screensaver in the window thread instead of the runner
thread so that there is no lock contention for the window lock in
the runner thread when the saver starts.

The view that gets drawn into is assumed to have been prepared before
being passed to the runner thread, and this assumption has been made
true for the screensaver preview and screen_blanker apps.

Eliminate fHasStarted and the corresponding HasStarted() method in
ScreenSaverRunner as they are no longer needed.

Drawing still happens in the runner thread, and still needs to lock
the window thread potentially causing contention, yet, there
is a timeout here so the contention won't freeze the screensaver window,
only delay drawing the screensaver.

Drawing could be moved to the window thread via message passing to avoid
lock contention with the window but this would defeat a big part of the
purpose of having a separate rendering thread.

This fixes #10125 and #4260
This commit is contained in:
John Scipione
2013-11-14 23:30:26 -05:00
parent 60c0a74844
commit d34a680c04
8 changed files with 117 additions and 124 deletions
@@ -12,24 +12,19 @@
#define SCREEN_SAVER_RUNNER_H
#include <SupportDefs.h>
#include <DirectWindow.h>
#include <ScreenSaver.h>
#include <View.h>
class BScreenSaver;
class BView;
class ScreenSaverSettings;
#include "ScreenSaverSettings.h"
class ScreenSaverRunner {
public:
ScreenSaverRunner(BWindow* window, BView* view,
bool preview,
ScreenSaverRunner(BView* view,
ScreenSaverSettings& settings);
~ScreenSaverRunner();
BScreenSaver* ScreenSaver() const;
bool HasStarted() const;
BScreenSaver* ScreenSaver() const { return fSaver; };
status_t Run();
void Quit();
@@ -43,13 +38,11 @@ private:
static status_t _ThreadFunc(void* data);
status_t _Run();
BScreenSaver* fSaver;
BWindow* fWindow;
BDirectWindow* fDirectWindow;
BView* fView;
bool fIsDirectDraw;
ScreenSaverSettings& fSettings;
bool fPreview;
bool fHasStarted;
BScreenSaver* fSaver;
image_id fAddonImage;
thread_id fThread;