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:
parent
8fb3930a42
commit
9e4096146f
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user