* The ScreenSaverFilter now uses locking in all public functions to ensure

it works well with its controlling looper. This fixes #2638.
* Header cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27885 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-10-06 09:41:59 +00:00
parent e1fafdf355
commit 94cd9aa2ed
2 changed files with 98 additions and 62 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007, Haiku. * Copyright 2003-2008, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -12,6 +12,7 @@
#include "ScreenSaverFilter.h" #include "ScreenSaverFilter.h"
#include <Application.h> #include <Application.h>
#include <Autolock.h>
#include <MessageRunner.h> #include <MessageRunner.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <OS.h> #include <OS.h>
@@ -101,23 +102,25 @@ ScreenSaverController::MessageReceived(BMessage *message)
ScreenSaverFilter::ScreenSaverFilter() ScreenSaverFilter::ScreenSaverFilter()
: : BLocker("screen saver filter"),
fLastEventTime(0), fLastEventTime(0),
fBlankTime(0), fBlankTime(0),
fSnoozeTime(0), fSnoozeTime(0),
fCurrentCorner(NO_CORNER), fCurrentCorner(NO_CORNER),
fEnabled(false),
fFrameNum(0), fFrameNum(0),
fRunner(NULL), fRunner(NULL),
fCornerRunner(NULL), fCornerRunner(NULL),
fWatchingDirectory(false), fWatchingDirectory(false),
fWatchingFile(false) fWatchingFile(false),
fEnabled(false)
{ {
CALLED(); CALLED();
fController = new (std::nothrow) ScreenSaverController(this); fController = new (std::nothrow) ScreenSaverController(this);
if (fController == NULL) if (fController == NULL)
return; return;
BAutolock _(this);
fController->Run(); fController->Run();
ReloadSettings(); ReloadSettings();
@@ -127,21 +130,23 @@ ScreenSaverFilter::ScreenSaverFilter()
ScreenSaverFilter::~ScreenSaverFilter() ScreenSaverFilter::~ScreenSaverFilter()
{ {
be_roster->StopWatching(fController);
// We must quit our controller without being locked, or else we might
// deadlock; when the controller is gone, there is no reason to lock
// anymore, anyway.
if (fController->Lock())
fController->Quit();
delete fCornerRunner; delete fCornerRunner;
delete fRunner; delete fRunner;
if (fWatchingFile || fWatchingDirectory) if (fWatchingFile || fWatchingDirectory)
watch_node(&fNodeRef, B_STOP_WATCHING, fController); watch_node(&fNodeRef, B_STOP_WATCHING, fController);
be_roster->StopWatching(fController);
if (fController->Lock())
fController->Quit();
} }
/*! /*! Starts watching the settings file, or if that doesn't exist, the directory
Starts watching the settings file, or if that doesn't exist, the directory
the settings file will be placed into. the settings file will be placed into.
*/ */
void void
@@ -176,6 +181,7 @@ ScreenSaverFilter::_WatchSettings()
} }
/*! Starts the screen saver if allowed */
void void
ScreenSaverFilter::_Invoke() ScreenSaverFilter::_Invoke()
{ {
@@ -192,10 +198,28 @@ ScreenSaverFilter::_Invoke()
} }
/*! Stops the running screen saver, if any */
void
ScreenSaverFilter::_Banish()
{
CALLED();
if (!fEnabled)
return;
SERIAL_PRINT(("we quit screenblanker\n"));
// Don't care if it fails
BMessenger blankerMessenger(SCREEN_BLANKER_SIG, -1, NULL);
blankerMessenger.SendMessage(B_QUIT_REQUESTED);
fEnabled = false;
}
void void
ScreenSaverFilter::ReloadSettings() ScreenSaverFilter::ReloadSettings()
{ {
CALLED(); CALLED();
BAutolock _(this);
bool isFirst = !fWatchingDirectory && !fWatchingFile; bool isFirst = !fWatchingDirectory && !fWatchingFile;
_WatchSettings(); _WatchSettings();
@@ -224,26 +248,19 @@ ScreenSaverFilter::ReloadSettings()
} }
BMessage check(kMsgCheckTime); BMessage check(kMsgCheckTime);
fRunner = new (std::nothrow) BMessageRunner(fController, &check, fSnoozeTime); fRunner = new (std::nothrow) BMessageRunner(fController, &check,
if (fRunner->InitCheck() != B_OK) { fSnoozeTime);
SERIAL_PRINT(("fRunner init failed\n")); if (fRunner == NULL || fRunner->InitCheck() != B_OK) {
SERIAL_PRINT(("screen saver filter runner init failed\n"));
} }
} }
void void
ScreenSaverFilter::_Banish() ScreenSaverFilter::SetEnabled(bool enabled)
{ {
CALLED(); BAutolock _(this);
if (!fEnabled) fEnabled = enabled;
return;
SERIAL_PRINT(("we quit screenblanker\n"));
// Don't care if it fails
BMessenger blankerMessenger(SCREEN_BLANKER_SIG, -1, NULL);
blankerMessenger.SendMessage(B_QUIT_REQUESTED);
fEnabled = false;
} }
@@ -251,6 +268,8 @@ void
ScreenSaverFilter::CheckTime() ScreenSaverFilter::CheckTime()
{ {
CALLED(); CALLED();
BAutolock _(this);
bigtime_t now = system_time(); bigtime_t now = system_time();
if (now >= fLastEventTime + fBlankTime) if (now >= fLastEventTime + fBlankTime)
_Invoke(); _Invoke();
@@ -267,7 +286,7 @@ ScreenSaverFilter::CheckTime()
else else
fSnoozeTime = fLastEventTime + fBlankTime - now; fSnoozeTime = fLastEventTime + fBlankTime - now;
if (fRunner) if (fRunner != NULL)
fRunner->SetInterval(fSnoozeTime); fRunner->SetInterval(fSnoozeTime);
} }
@@ -275,6 +294,8 @@ ScreenSaverFilter::CheckTime()
void void
ScreenSaverFilter::CheckCornerInvoke() ScreenSaverFilter::CheckCornerInvoke()
{ {
BAutolock _(this);
bigtime_t inactivity = system_time() - fLastEventTime; bigtime_t inactivity = system_time() - fLastEventTime;
if (fCurrentCorner == fBlankCorner && fBlankCorner != NO_CORNER if (fCurrentCorner == fBlankCorner && fBlankCorner != NO_CORNER
@@ -326,6 +347,8 @@ ScreenSaverFilter::_ScreenCorner(screen_corner corner, uint32 cornerSize)
filter_result filter_result
ScreenSaverFilter::Filter(BMessage *message, BList *outList) ScreenSaverFilter::Filter(BMessage *message, BList *outList)
{ {
BAutolock _(this);
fLastEventTime = system_time(); fLastEventTime = system_time();
switch (message->what) { switch (message->what) {
@@ -366,7 +389,8 @@ ScreenSaverFilter::Filter(BMessage *message, BList *outList)
// we ignore the Print-Screen key to make screen shots of // we ignore the Print-Screen key to make screen shots of
// screen savers possible // screen savers possible
int32 key; int32 key;
if (fEnabled && message->FindInt32("key", &key) == B_OK && key == 0xe) if (fEnabled && message->FindInt32("key", &key) == B_OK
&& key == 0xe)
return B_DISPATCH_MESSAGE; return B_DISPATCH_MESSAGE;
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2006, Haiku. * Copyright 2003-2008, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -14,6 +14,7 @@
#include "ScreenSaverSettings.h" #include "ScreenSaverSettings.h"
#include <InputServerFilter.h> #include <InputServerFilter.h>
#include <Locker.h>
#include <Looper.h> #include <Looper.h>
#include <Node.h> #include <Node.h>
@@ -23,16 +24,19 @@ static const uint32 kMsgSuspendScreenSaver = 'susp';
class BMessageRunner; class BMessageRunner;
class ScreenSaverFilter; class ScreenSaverFilter;
class ScreenSaverController : public BLooper { class ScreenSaverController : public BLooper {
public: public:
ScreenSaverController(ScreenSaverFilter *filter); ScreenSaverController(
void MessageReceived(BMessage *msg); ScreenSaverFilter* filter);
virtual void MessageReceived(BMessage* msg);
private: private:
ScreenSaverFilter* fFilter; ScreenSaverFilter* fFilter;
}; };
class ScreenSaverFilter : public BInputServerFilter {
class ScreenSaverFilter : public BInputServerFilter, BLocker {
public: public:
ScreenSaverFilter(); ScreenSaverFilter();
virtual ~ScreenSaverFilter(); virtual ~ScreenSaverFilter();
@@ -44,30 +48,38 @@ class ScreenSaverFilter : public BInputServerFilter {
void CheckTime(); void CheckTime();
void CheckCornerInvoke(); void CheckCornerInvoke();
uint32 SnoozeTime() {return fSnoozeTime;}
void ReloadSettings(); void ReloadSettings();
void SetEnabled(bool enabled) { fEnabled = enabled; } void SetEnabled(bool enabled);
private: private:
uint32 _SnoozeTime() {return fSnoozeTime;}
void _WatchSettings(); void _WatchSettings();
void _UpdateRectangles(); void _UpdateRectangles();
BRect _ScreenCorner(screen_corner pos, uint32 cornerSize); BRect _ScreenCorner(screen_corner pos,
uint32 cornerSize);
void _Invoke(); void _Invoke();
void _Banish(); void _Banish();
ScreenSaverSettings fSettings; ScreenSaverSettings fSettings;
bigtime_t fLastEventTime, fBlankTime, fSnoozeTime; bigtime_t fLastEventTime;
screen_corner fBlankCorner, fNeverBlankCorner, fCurrentCorner; bigtime_t fBlankTime;
BRect fBlankRect, fNeverBlankRect; bigtime_t fSnoozeTime;
bool fEnabled; screen_corner fBlankCorner;
screen_corner fNeverBlankCorner;
screen_corner fCurrentCorner;
BRect fBlankRect;
BRect fNeverBlankRect;
uint32 fFrameNum; uint32 fFrameNum;
ScreenSaverController* fController; ScreenSaverController* fController;
node_ref fNodeRef; node_ref fNodeRef;
BMessageRunner* fRunner; BMessageRunner* fRunner;
BMessageRunner* fCornerRunner; BMessageRunner* fCornerRunner;
bool fWatchingDirectory, fWatchingFile; bool fWatchingDirectory;
bool fWatchingFile;
bool fEnabled;
}; };
#endif /* SCREEN_SAVER_FILTER_H */ #endif /* SCREEN_SAVER_FILTER_H */