package daemon: Add a Listener interface for Volume

* This way, Volume doesn't have to know Root.
* Suppress listener notifications for node monitoring events when there
  are were already events pending.
This commit is contained in:
Ingo Weinhold 2013-04-08 15:19:11 +02:00
parent 8fb3930a42
commit 9e4096146f
4 changed files with 48 additions and 14 deletions

View File

@ -14,7 +14,6 @@
#include <Path.h>
#include "DebugSupport.h"
#include "Volume.h"
// #pragma mark - InitVolumePackagesJob
@ -29,7 +28,7 @@ struct Root::InitPackagesJob : public Job {
virtual void Do()
{
fVolume->InitPackages();
fVolume->InitPackages(fVolume->GetRoot());
}
private:
@ -210,9 +209,8 @@ Root::FindVolume(dev_t deviceID) const
void
Root::HandleNodeMonitorEvents(Volume* volume)
Root::VolumeNodeMonitorEventOccurred(Volume* volume)
{
// TODO: Don't push a new one, if one is already pending!
_QueueJob(new(std::nothrow) HandleNodeMonitorEventsJob(volume));
}

View File

@ -19,12 +19,10 @@
#include <packagefs.h>
#include "JobQueue.h"
#include "Volume.h"
class Volume;
class Root : public BReferenceable {
class Root : public BReferenceable, private Volume::Listener {
public:
Root();
virtual ~Root();
@ -42,7 +40,9 @@ public:
Volume* FindVolume(dev_t deviceID) const;
void HandleNodeMonitorEvents(Volume* volume);
private:
// Volume::Listener
virtual void VolumeNodeMonitorEventOccurred(Volume* volume);
protected:
virtual void LastReferenceReleased();
@ -52,6 +52,8 @@ private:
struct DeleteVolumeJob;
struct HandleNodeMonitorEventsJob;
friend struct InitPackagesJob;
private:
Volume** _GetVolume(PackageFSMountType mountType);

View File

@ -24,7 +24,14 @@
#include <AutoLocker.h>
#include "DebugSupport.h"
#include "Root.h"
// #pragma mark - Listener
Volume::Listener::~Listener()
{
}
// #pragma mark - NodeMonitorEvent
@ -67,6 +74,7 @@ Volume::Volume(BLooper* looper)
fRootDirectoryRef(),
fPackagesDirectoryRef(),
fRoot(NULL),
fListener(NULL),
fPackagesByFileName(),
fPackagesByNodeRef(),
fPendingNodeMonitorEventsLock("pending node monitor events"),
@ -78,6 +86,9 @@ Volume::Volume(BLooper* looper)
Volume::~Volume()
{
Unmounted();
// need for error case in InitPackages()
fPackagesByFileName.Clear();
Package* package = fPackagesByNodeRef.Clear(true);
@ -153,7 +164,7 @@ Volume::Init(const node_ref& rootDirectoryRef, node_ref& _packageRootRef)
status_t
Volume::InitPackages()
Volume::InitPackages(Listener* listener)
{
// node-monitor the volume's packages directory
status_t error = watch_node(&fPackagesDirectoryRef, B_WATCH_DIRECTORY,
@ -166,6 +177,8 @@ Volume::InitPackages()
// packages directory won't work correctly.
}
fListener = listener;
// read the packages directory and get the active packages
int fd = OpenRootDirectory();
if (fd < 0) {
@ -190,7 +203,13 @@ Volume::InitPackages()
void
Volume::Unmounted()
{
stop_watching(BMessenger(this));
if (fListener != NULL) {
stop_watching(BMessenger(this));
fListener = NULL;
}
if (BLooper* looper = Looper())
looper->RemoveHandler(this);
}
@ -324,10 +343,12 @@ Volume::_QueueNodeMonitorEvent(const BString& name, bool wasCreated)
}
AutoLocker<BLocker> eventsLock(fPendingNodeMonitorEventsLock);
bool firstEvent = fPendingNodeMonitorEvents.IsEmpty();
fPendingNodeMonitorEvents.Add(event);
eventsLock.Unlock();
fRoot->HandleNodeMonitorEvents(this);
if (firstEvent && fListener != NULL)
fListener->VolumeNodeMonitorEventOccurred(this);
}

View File

@ -25,13 +25,16 @@ class Root;
class Volume : public BHandler {
public:
class Listener;
public:
Volume(BLooper* looper);
virtual ~Volume();
status_t Init(const node_ref& rootDirectoryRef,
node_ref& _packageRootRef);
status_t InitPackages();
status_t InitPackages(Listener* listener);
void Unmounted();
@ -88,6 +91,7 @@ private:
node_ref fRootDirectoryRef;
node_ref fPackagesDirectoryRef;
Root* fRoot;
Listener* fListener;
PackageFileNameHashTable fPackagesByFileName;
PackageNodeRefHashTable fPackagesByNodeRef;
BLocker fPendingNodeMonitorEventsLock;
@ -95,4 +99,13 @@ private:
};
class Volume::Listener {
public:
virtual ~Listener();
virtual void VolumeNodeMonitorEventOccurred(Volume* volume)
= 0;
};
#endif // VOLUME_H