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:
@@ -14,7 +14,6 @@
|
|||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "Volume.h"
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - InitVolumePackagesJob
|
// #pragma mark - InitVolumePackagesJob
|
||||||
@@ -29,7 +28,7 @@ struct Root::InitPackagesJob : public Job {
|
|||||||
|
|
||||||
virtual void Do()
|
virtual void Do()
|
||||||
{
|
{
|
||||||
fVolume->InitPackages();
|
fVolume->InitPackages(fVolume->GetRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -210,9 +209,8 @@ Root::FindVolume(dev_t deviceID) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
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));
|
_QueueJob(new(std::nothrow) HandleNodeMonitorEventsJob(volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,10 @@
|
|||||||
#include <packagefs.h>
|
#include <packagefs.h>
|
||||||
|
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
class Volume;
|
class Root : public BReferenceable, private Volume::Listener {
|
||||||
|
|
||||||
|
|
||||||
class Root : public BReferenceable {
|
|
||||||
public:
|
public:
|
||||||
Root();
|
Root();
|
||||||
virtual ~Root();
|
virtual ~Root();
|
||||||
@@ -42,7 +40,9 @@ public:
|
|||||||
|
|
||||||
Volume* FindVolume(dev_t deviceID) const;
|
Volume* FindVolume(dev_t deviceID) const;
|
||||||
|
|
||||||
void HandleNodeMonitorEvents(Volume* volume);
|
private:
|
||||||
|
// Volume::Listener
|
||||||
|
virtual void VolumeNodeMonitorEventOccurred(Volume* volume);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void LastReferenceReleased();
|
virtual void LastReferenceReleased();
|
||||||
@@ -52,6 +52,8 @@ private:
|
|||||||
struct DeleteVolumeJob;
|
struct DeleteVolumeJob;
|
||||||
struct HandleNodeMonitorEventsJob;
|
struct HandleNodeMonitorEventsJob;
|
||||||
|
|
||||||
|
friend struct InitPackagesJob;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Volume** _GetVolume(PackageFSMountType mountType);
|
Volume** _GetVolume(PackageFSMountType mountType);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,14 @@
|
|||||||
#include <AutoLocker.h>
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "Root.h"
|
|
||||||
|
|
||||||
|
// #pragma mark - Listener
|
||||||
|
|
||||||
|
|
||||||
|
Volume::Listener::~Listener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - NodeMonitorEvent
|
// #pragma mark - NodeMonitorEvent
|
||||||
@@ -67,6 +74,7 @@ Volume::Volume(BLooper* looper)
|
|||||||
fRootDirectoryRef(),
|
fRootDirectoryRef(),
|
||||||
fPackagesDirectoryRef(),
|
fPackagesDirectoryRef(),
|
||||||
fRoot(NULL),
|
fRoot(NULL),
|
||||||
|
fListener(NULL),
|
||||||
fPackagesByFileName(),
|
fPackagesByFileName(),
|
||||||
fPackagesByNodeRef(),
|
fPackagesByNodeRef(),
|
||||||
fPendingNodeMonitorEventsLock("pending node monitor events"),
|
fPendingNodeMonitorEventsLock("pending node monitor events"),
|
||||||
@@ -78,6 +86,9 @@ Volume::Volume(BLooper* looper)
|
|||||||
|
|
||||||
Volume::~Volume()
|
Volume::~Volume()
|
||||||
{
|
{
|
||||||
|
Unmounted();
|
||||||
|
// need for error case in InitPackages()
|
||||||
|
|
||||||
fPackagesByFileName.Clear();
|
fPackagesByFileName.Clear();
|
||||||
|
|
||||||
Package* package = fPackagesByNodeRef.Clear(true);
|
Package* package = fPackagesByNodeRef.Clear(true);
|
||||||
@@ -153,7 +164,7 @@ Volume::Init(const node_ref& rootDirectoryRef, node_ref& _packageRootRef)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::InitPackages()
|
Volume::InitPackages(Listener* listener)
|
||||||
{
|
{
|
||||||
// node-monitor the volume's packages directory
|
// node-monitor the volume's packages directory
|
||||||
status_t error = watch_node(&fPackagesDirectoryRef, B_WATCH_DIRECTORY,
|
status_t error = watch_node(&fPackagesDirectoryRef, B_WATCH_DIRECTORY,
|
||||||
@@ -166,6 +177,8 @@ Volume::InitPackages()
|
|||||||
// packages directory won't work correctly.
|
// packages directory won't work correctly.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fListener = listener;
|
||||||
|
|
||||||
// read the packages directory and get the active packages
|
// read the packages directory and get the active packages
|
||||||
int fd = OpenRootDirectory();
|
int fd = OpenRootDirectory();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -190,7 +203,13 @@ Volume::InitPackages()
|
|||||||
void
|
void
|
||||||
Volume::Unmounted()
|
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);
|
AutoLocker<BLocker> eventsLock(fPendingNodeMonitorEventsLock);
|
||||||
|
bool firstEvent = fPendingNodeMonitorEvents.IsEmpty();
|
||||||
fPendingNodeMonitorEvents.Add(event);
|
fPendingNodeMonitorEvents.Add(event);
|
||||||
eventsLock.Unlock();
|
eventsLock.Unlock();
|
||||||
|
|
||||||
fRoot->HandleNodeMonitorEvents(this);
|
if (firstEvent && fListener != NULL)
|
||||||
|
fListener->VolumeNodeMonitorEventOccurred(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,16 @@ class Root;
|
|||||||
|
|
||||||
|
|
||||||
class Volume : public BHandler {
|
class Volume : public BHandler {
|
||||||
|
public:
|
||||||
|
class Listener;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Volume(BLooper* looper);
|
Volume(BLooper* looper);
|
||||||
virtual ~Volume();
|
virtual ~Volume();
|
||||||
|
|
||||||
status_t Init(const node_ref& rootDirectoryRef,
|
status_t Init(const node_ref& rootDirectoryRef,
|
||||||
node_ref& _packageRootRef);
|
node_ref& _packageRootRef);
|
||||||
status_t InitPackages();
|
status_t InitPackages(Listener* listener);
|
||||||
|
|
||||||
void Unmounted();
|
void Unmounted();
|
||||||
|
|
||||||
@@ -88,6 +91,7 @@ private:
|
|||||||
node_ref fRootDirectoryRef;
|
node_ref fRootDirectoryRef;
|
||||||
node_ref fPackagesDirectoryRef;
|
node_ref fPackagesDirectoryRef;
|
||||||
Root* fRoot;
|
Root* fRoot;
|
||||||
|
Listener* fListener;
|
||||||
PackageFileNameHashTable fPackagesByFileName;
|
PackageFileNameHashTable fPackagesByFileName;
|
||||||
PackageNodeRefHashTable fPackagesByNodeRef;
|
PackageNodeRefHashTable fPackagesByNodeRef;
|
||||||
BLocker fPendingNodeMonitorEventsLock;
|
BLocker fPendingNodeMonitorEventsLock;
|
||||||
@@ -95,4 +99,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Volume::Listener {
|
||||||
|
public:
|
||||||
|
virtual ~Listener();
|
||||||
|
|
||||||
|
virtual void VolumeNodeMonitorEventOccurred(Volume* volume)
|
||||||
|
= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // VOLUME_H
|
#endif // VOLUME_H
|
||||||
|
|||||||
Reference in New Issue
Block a user