Add package link directories to system volume
* Add PackageLinksListener interface. It is used by PackageLink[s]Directory to notify a listener about changes. * Volume does now implement PackageLinksListener and recursively adds/ removes package link directories. This makes the package link directories appear at least. They are still empty.
This commit is contained in:
parent
4031a32acc
commit
3e7333b7c1
@ -25,6 +25,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
||||
PackageLeafNode.cpp
|
||||
PackageLinkDirectory.cpp
|
||||
PackageLinksDirectory.cpp
|
||||
PackageLinksListener.cpp
|
||||
PackageNode.cpp
|
||||
PackageNodeAttribute.cpp
|
||||
PackageSymlink.cpp
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "EmptyAttributeDirectoryCookie.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "PackageLinksListener.h"
|
||||
#include "Utils.h"
|
||||
#include "Version.h"
|
||||
|
||||
@ -60,7 +61,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// add the package
|
||||
AddPackage(package);
|
||||
AddPackage(package, NULL);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -131,21 +132,40 @@ PackageLinkDirectory::OpenAttribute(const char* name, int openMode,
|
||||
|
||||
|
||||
void
|
||||
PackageLinkDirectory::AddPackage(Package* package)
|
||||
PackageLinkDirectory::AddPackage(Package* package,
|
||||
PackageLinksListener* listener)
|
||||
{
|
||||
NodeWriteLocker writeLocker(this);
|
||||
|
||||
if (listener != NULL)
|
||||
listener->PackageLinkDirectoryRemoved(this);
|
||||
|
||||
// TODO: Add in priority order!
|
||||
fPackages.Add(package);
|
||||
package->SetLinkDirectory(this);
|
||||
|
||||
if (listener != NULL)
|
||||
listener->PackageLinkDirectoryAdded(this);
|
||||
// TODO: The notifications should only happen as necessary!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageLinkDirectory::RemovePackage(Package* package)
|
||||
PackageLinkDirectory::RemovePackage(Package* package,
|
||||
PackageLinksListener* listener)
|
||||
{
|
||||
|
||||
ASSERT(package->LinkDirectory() == this);
|
||||
|
||||
NodeWriteLocker writeLocker(this);
|
||||
|
||||
if (listener != NULL)
|
||||
listener->PackageLinkDirectoryRemoved(this);
|
||||
|
||||
package->SetLinkDirectory(NULL);
|
||||
fPackages.Remove(package);
|
||||
// TODO: Check whether that was the top priority package!
|
||||
|
||||
if (listener != NULL && !IsEmpty())
|
||||
listener->PackageLinkDirectoryAdded(this);
|
||||
// TODO: The notifications should only happen as necessary!
|
||||
}
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "Package.h"
|
||||
|
||||
|
||||
class PackageLinksListener;
|
||||
|
||||
|
||||
class PackageLinkDirectory : public Directory {
|
||||
public:
|
||||
PackageLinkDirectory();
|
||||
@ -29,8 +32,10 @@ public:
|
||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||
AttributeCookie*& _cookie);
|
||||
|
||||
void AddPackage(Package* package);
|
||||
void RemovePackage(Package* package);
|
||||
void AddPackage(Package* package,
|
||||
PackageLinksListener* listener);
|
||||
void RemovePackage(Package* package,
|
||||
PackageLinksListener* listener);
|
||||
|
||||
bool IsEmpty() const
|
||||
{ return fPackages.IsEmpty(); }
|
||||
|
@ -11,12 +11,14 @@
|
||||
#include "EmptyAttributeDirectoryCookie.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "PackageLinkDirectory.h"
|
||||
#include "PackageLinksListener.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
PackageLinksDirectory::PackageLinksDirectory()
|
||||
:
|
||||
Directory(0)
|
||||
Directory(0),
|
||||
fListener(NULL)
|
||||
// the ID needs to be assigned later, when added to a volume
|
||||
{
|
||||
get_real_time(fModifiedTime);
|
||||
@ -111,18 +113,26 @@ PackageLinksDirectory::AddPackage(Package* package)
|
||||
// add the link directory
|
||||
NodeWriteLocker writeLocker(this);
|
||||
if (Node* child = FindChild(linkDirectory->Name())) {
|
||||
// There already is an entry with the name.
|
||||
PackageLinkDirectory* otherLinkDirectory
|
||||
= dynamic_cast<PackageLinkDirectory*>(child);
|
||||
if (otherLinkDirectory != NULL)
|
||||
RETURN_ERROR(B_BAD_VALUE);
|
||||
|
||||
linkDirectory->RemovePackage(package);
|
||||
// There's already a package link directory. Delete the one we created
|
||||
// and add the package to the pre-existing one.
|
||||
linkDirectory->RemovePackage(package, NULL);
|
||||
linkDirectory = otherLinkDirectory;
|
||||
linkDirectory->AddPackage(package);
|
||||
} else
|
||||
linkDirectory->AddPackage(package, fListener);
|
||||
} else {
|
||||
// No entry is in the way, so just add the link directory.
|
||||
AddChild(linkDirectory);
|
||||
|
||||
// TODO:...
|
||||
if (fListener != NULL) {
|
||||
NodeWriteLocker linkDirectoryWriteLocker(linkDirectory);
|
||||
fListener->PackageLinkDirectoryAdded(linkDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -140,12 +150,10 @@ PackageLinksDirectory::RemovePackage(Package* package)
|
||||
|
||||
NodeWriteLocker writeLocker(this);
|
||||
|
||||
linkDirectory->RemovePackage(package);
|
||||
linkDirectory->RemovePackage(package, fListener);
|
||||
|
||||
// if empty, remove the link directory itself
|
||||
if (linkDirectory->IsEmpty())
|
||||
RemoveChild(linkDirectory);
|
||||
|
||||
// TODO:...
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
class Package;
|
||||
class PackageLinksListener;
|
||||
|
||||
|
||||
class PackageLinksDirectory : public Directory {
|
||||
@ -30,11 +31,15 @@ public:
|
||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||
AttributeCookie*& _cookie);
|
||||
|
||||
void SetListener(PackageLinksListener* listener)
|
||||
{ fListener = listener; }
|
||||
|
||||
status_t AddPackage(Package* package);
|
||||
void RemovePackage(Package* package);
|
||||
|
||||
private:
|
||||
timespec fModifiedTime;
|
||||
PackageLinksListener* fListener;
|
||||
};
|
||||
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackageLinksListener.h"
|
||||
|
||||
|
||||
|
||||
PackageLinksListener::~PackageLinksListener()
|
||||
{
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_LINKS_LISTENER_H
|
||||
#define PACKAGE_LINKS_LISTENER_H
|
||||
|
||||
|
||||
class PackageLinkDirectory;
|
||||
|
||||
|
||||
class PackageLinksListener {
|
||||
public:
|
||||
virtual ~PackageLinksListener();
|
||||
|
||||
virtual void PackageLinkDirectoryAdded(
|
||||
PackageLinkDirectory* directory) = 0;
|
||||
virtual void PackageLinkDirectoryRemoved(
|
||||
PackageLinkDirectory* directory) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // PACKAGE_LINKS_LISTENER_H
|
@ -35,6 +35,7 @@
|
||||
#include "PackageDirectory.h"
|
||||
#include "PackageFile.h"
|
||||
#include "PackageFSRoot.h"
|
||||
#include "PackageLinkDirectory.h"
|
||||
#include "PackageLinksDirectory.h"
|
||||
#include "PackageSymlink.h"
|
||||
#include "Resolvable.h"
|
||||
@ -619,6 +620,20 @@ Volume::AddPackageDomain(const char* path)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::PackageLinkDirectoryAdded(PackageLinkDirectory* directory)
|
||||
{
|
||||
_AddPackageLinksNode(directory);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::PackageLinkDirectoryRemoved(PackageLinkDirectory* directory)
|
||||
{
|
||||
_RemovePackageLinksNode(directory);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
Volume::_PackageLoaderEntry(void* data)
|
||||
{
|
||||
@ -734,6 +749,7 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify)
|
||||
}
|
||||
|
||||
// add the packages to the node tree
|
||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||
VolumeWriteLocker volumeLocker(this);
|
||||
for (PackageFileNameHashTable::Iterator it
|
||||
= domain->Packages().GetIterator(); Package* package = it.Next();) {
|
||||
@ -1216,6 +1232,7 @@ Volume::_DomainEntryCreated(PackageDomain* domain, dev_t deviceID,
|
||||
if (error != B_OK)
|
||||
return;
|
||||
|
||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||
VolumeWriteLocker volumeLocker(this);
|
||||
domain->AddPackage(package);
|
||||
|
||||
@ -1244,6 +1261,7 @@ Volume::_DomainEntryRemoved(PackageDomain* domain, dev_t deviceID,
|
||||
BReference<Package> packageReference(package);
|
||||
|
||||
// remove the package
|
||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||
VolumeWriteLocker volumeLocker(this);
|
||||
_RemovePackageContent(package, NULL, true);
|
||||
domain->RemovePackage(package);
|
||||
@ -1388,12 +1406,12 @@ Volume::_AddPackageLinksDirectory()
|
||||
NodeWriteLocker rootDirectoryWriteLocker(fRootDirectory);
|
||||
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
||||
|
||||
packageLinksDirectory->SetID(fNextNodeID++);
|
||||
packageLinksDirectory->SetParent(fRootDirectory);
|
||||
|
||||
fRootDirectory->AddChild(packageLinksDirectory);
|
||||
fNodes.Insert(packageLinksDirectory);
|
||||
packageLinksDirectory->AcquireReference();
|
||||
|
||||
_AddPackageLinksNode(packageLinksDirectory);
|
||||
|
||||
packageLinksDirectory->SetListener(this);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -1410,7 +1428,54 @@ Volume::_RemovePackageLinksDirectory()
|
||||
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
||||
|
||||
if (packageLinksDirectory->Parent() == fRootDirectory) {
|
||||
_RemoveNode(packageLinksDirectory);
|
||||
packageLinksDirectory->SetListener(NULL);
|
||||
_RemovePackageLinksNode(packageLinksDirectory);
|
||||
packageLinksDirectory->SetParent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::_AddPackageLinksNode(Node* node)
|
||||
{
|
||||
node->SetID(fNextNodeID++);
|
||||
|
||||
fNodes.Insert(node);
|
||||
node->AcquireReference();
|
||||
|
||||
// If this is a directory, recursively add descendants. The directory tree
|
||||
// for the package links isn't deep, so we can do recursion.
|
||||
if (Directory* directory = dynamic_cast<Directory*>(node)) {
|
||||
for (Node* child = directory->FirstChild(); child != NULL;
|
||||
child = directory->NextChild(child)) {
|
||||
NodeWriteLocker childWriteLocker(child);
|
||||
_AddPackageLinksNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::_RemovePackageLinksNode(Node* node)
|
||||
{
|
||||
// If this is a directory, recursively remove descendants. The directory
|
||||
// tree for the package links isn't deep, so we can do recursion.
|
||||
if (Directory* directory = dynamic_cast<Directory*>(node)) {
|
||||
for (Node* child = directory->FirstChild(); child != NULL;
|
||||
child = directory->NextChild(child)) {
|
||||
NodeWriteLocker childWriteLocker(child);
|
||||
_RemovePackageLinksNode(child);
|
||||
}
|
||||
}
|
||||
|
||||
_RemoveNode(node);
|
||||
}
|
||||
|
||||
|
||||
inline Volume*
|
||||
Volume::_SystemVolumeIfNotSelf() const
|
||||
{
|
||||
if (Volume* systemVolume = fPackageFSRoot->SystemVolume())
|
||||
return systemVolume == this ? NULL : systemVolume;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "Node.h"
|
||||
#include "PackageDomain.h"
|
||||
#include "PackageLinksListener.h"
|
||||
|
||||
|
||||
class Directory;
|
||||
@ -32,7 +33,8 @@ enum MountType {
|
||||
};
|
||||
|
||||
|
||||
class Volume : public DoublyLinkedListLinkImpl<Volume> {
|
||||
class Volume : public DoublyLinkedListLinkImpl<Volume>,
|
||||
private PackageLinksListener {
|
||||
public:
|
||||
Volume(fs_volume* fsVolume);
|
||||
~Volume();
|
||||
@ -72,6 +74,13 @@ public:
|
||||
|
||||
status_t AddPackageDomain(const char* path);
|
||||
|
||||
private:
|
||||
// PackageLinksListener
|
||||
virtual void PackageLinkDirectoryAdded(
|
||||
PackageLinkDirectory* directory);
|
||||
virtual void PackageLinkDirectoryRemoved(
|
||||
PackageLinkDirectory* directory);
|
||||
|
||||
private:
|
||||
struct Job;
|
||||
struct AddPackageDomainJob;
|
||||
@ -147,6 +156,10 @@ private:
|
||||
|
||||
status_t _AddPackageLinksDirectory();
|
||||
void _RemovePackageLinksDirectory();
|
||||
void _AddPackageLinksNode(Node* node);
|
||||
void _RemovePackageLinksNode(Node* node);
|
||||
|
||||
inline Volume* _SystemVolumeIfNotSelf() const;
|
||||
|
||||
private:
|
||||
mutable rw_lock fLock;
|
||||
|
Loading…
Reference in New Issue
Block a user