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
|
PackageLeafNode.cpp
|
||||||
PackageLinkDirectory.cpp
|
PackageLinkDirectory.cpp
|
||||||
PackageLinksDirectory.cpp
|
PackageLinksDirectory.cpp
|
||||||
|
PackageLinksListener.cpp
|
||||||
PackageNode.cpp
|
PackageNode.cpp
|
||||||
PackageNodeAttribute.cpp
|
PackageNodeAttribute.cpp
|
||||||
PackageSymlink.cpp
|
PackageSymlink.cpp
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "EmptyAttributeDirectoryCookie.h"
|
#include "EmptyAttributeDirectoryCookie.h"
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
|
#include "PackageLinksListener.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
|
|||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// add the package
|
// add the package
|
||||||
AddPackage(package);
|
AddPackage(package, NULL);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -131,21 +132,40 @@ PackageLinkDirectory::OpenAttribute(const char* name, int openMode,
|
|||||||
|
|
||||||
|
|
||||||
void
|
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!
|
// TODO: Add in priority order!
|
||||||
fPackages.Add(package);
|
fPackages.Add(package);
|
||||||
package->SetLinkDirectory(this);
|
package->SetLinkDirectory(this);
|
||||||
|
|
||||||
|
if (listener != NULL)
|
||||||
|
listener->PackageLinkDirectoryAdded(this);
|
||||||
|
// TODO: The notifications should only happen as necessary!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PackageLinkDirectory::RemovePackage(Package* package)
|
PackageLinkDirectory::RemovePackage(Package* package,
|
||||||
|
PackageLinksListener* listener)
|
||||||
{
|
{
|
||||||
|
|
||||||
ASSERT(package->LinkDirectory() == this);
|
ASSERT(package->LinkDirectory() == this);
|
||||||
|
|
||||||
|
NodeWriteLocker writeLocker(this);
|
||||||
|
|
||||||
|
if (listener != NULL)
|
||||||
|
listener->PackageLinkDirectoryRemoved(this);
|
||||||
|
|
||||||
package->SetLinkDirectory(NULL);
|
package->SetLinkDirectory(NULL);
|
||||||
fPackages.Remove(package);
|
fPackages.Remove(package);
|
||||||
// TODO: Check whether that was the top priority 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"
|
#include "Package.h"
|
||||||
|
|
||||||
|
|
||||||
|
class PackageLinksListener;
|
||||||
|
|
||||||
|
|
||||||
class PackageLinkDirectory : public Directory {
|
class PackageLinkDirectory : public Directory {
|
||||||
public:
|
public:
|
||||||
PackageLinkDirectory();
|
PackageLinkDirectory();
|
||||||
@ -29,8 +32,10 @@ public:
|
|||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie);
|
AttributeCookie*& _cookie);
|
||||||
|
|
||||||
void AddPackage(Package* package);
|
void AddPackage(Package* package,
|
||||||
void RemovePackage(Package* package);
|
PackageLinksListener* listener);
|
||||||
|
void RemovePackage(Package* package,
|
||||||
|
PackageLinksListener* listener);
|
||||||
|
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
{ return fPackages.IsEmpty(); }
|
{ return fPackages.IsEmpty(); }
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
#include "EmptyAttributeDirectoryCookie.h"
|
#include "EmptyAttributeDirectoryCookie.h"
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "PackageLinkDirectory.h"
|
#include "PackageLinkDirectory.h"
|
||||||
|
#include "PackageLinksListener.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
|
||||||
PackageLinksDirectory::PackageLinksDirectory()
|
PackageLinksDirectory::PackageLinksDirectory()
|
||||||
:
|
:
|
||||||
Directory(0)
|
Directory(0),
|
||||||
|
fListener(NULL)
|
||||||
// the ID needs to be assigned later, when added to a volume
|
// the ID needs to be assigned later, when added to a volume
|
||||||
{
|
{
|
||||||
get_real_time(fModifiedTime);
|
get_real_time(fModifiedTime);
|
||||||
@ -111,18 +113,26 @@ PackageLinksDirectory::AddPackage(Package* package)
|
|||||||
// add the link directory
|
// add the link directory
|
||||||
NodeWriteLocker writeLocker(this);
|
NodeWriteLocker writeLocker(this);
|
||||||
if (Node* child = FindChild(linkDirectory->Name())) {
|
if (Node* child = FindChild(linkDirectory->Name())) {
|
||||||
|
// There already is an entry with the name.
|
||||||
PackageLinkDirectory* otherLinkDirectory
|
PackageLinkDirectory* otherLinkDirectory
|
||||||
= dynamic_cast<PackageLinkDirectory*>(child);
|
= dynamic_cast<PackageLinkDirectory*>(child);
|
||||||
if (otherLinkDirectory != NULL)
|
if (otherLinkDirectory != NULL)
|
||||||
RETURN_ERROR(B_BAD_VALUE);
|
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 = otherLinkDirectory;
|
||||||
linkDirectory->AddPackage(package);
|
linkDirectory->AddPackage(package, fListener);
|
||||||
} else
|
} else {
|
||||||
|
// No entry is in the way, so just add the link directory.
|
||||||
AddChild(linkDirectory);
|
AddChild(linkDirectory);
|
||||||
|
|
||||||
// TODO:...
|
if (fListener != NULL) {
|
||||||
|
NodeWriteLocker linkDirectoryWriteLocker(linkDirectory);
|
||||||
|
fListener->PackageLinkDirectoryAdded(linkDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -140,12 +150,10 @@ PackageLinksDirectory::RemovePackage(Package* package)
|
|||||||
|
|
||||||
NodeWriteLocker writeLocker(this);
|
NodeWriteLocker writeLocker(this);
|
||||||
|
|
||||||
linkDirectory->RemovePackage(package);
|
linkDirectory->RemovePackage(package, fListener);
|
||||||
|
|
||||||
// if empty, remove the link directory itself
|
// if empty, remove the link directory itself
|
||||||
if (linkDirectory->IsEmpty())
|
if (linkDirectory->IsEmpty())
|
||||||
RemoveChild(linkDirectory);
|
RemoveChild(linkDirectory);
|
||||||
|
|
||||||
// TODO:...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Package;
|
class Package;
|
||||||
|
class PackageLinksListener;
|
||||||
|
|
||||||
|
|
||||||
class PackageLinksDirectory : public Directory {
|
class PackageLinksDirectory : public Directory {
|
||||||
@ -30,11 +31,15 @@ public:
|
|||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie);
|
AttributeCookie*& _cookie);
|
||||||
|
|
||||||
|
void SetListener(PackageLinksListener* listener)
|
||||||
|
{ fListener = listener; }
|
||||||
|
|
||||||
status_t AddPackage(Package* package);
|
status_t AddPackage(Package* package);
|
||||||
void RemovePackage(Package* package);
|
void RemovePackage(Package* package);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
timespec fModifiedTime;
|
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 "PackageDirectory.h"
|
||||||
#include "PackageFile.h"
|
#include "PackageFile.h"
|
||||||
#include "PackageFSRoot.h"
|
#include "PackageFSRoot.h"
|
||||||
|
#include "PackageLinkDirectory.h"
|
||||||
#include "PackageLinksDirectory.h"
|
#include "PackageLinksDirectory.h"
|
||||||
#include "PackageSymlink.h"
|
#include "PackageSymlink.h"
|
||||||
#include "Resolvable.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
|
/*static*/ status_t
|
||||||
Volume::_PackageLoaderEntry(void* data)
|
Volume::_PackageLoaderEntry(void* data)
|
||||||
{
|
{
|
||||||
@ -734,6 +749,7 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add the packages to the node tree
|
// add the packages to the node tree
|
||||||
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
VolumeWriteLocker volumeLocker(this);
|
VolumeWriteLocker volumeLocker(this);
|
||||||
for (PackageFileNameHashTable::Iterator it
|
for (PackageFileNameHashTable::Iterator it
|
||||||
= domain->Packages().GetIterator(); Package* package = it.Next();) {
|
= domain->Packages().GetIterator(); Package* package = it.Next();) {
|
||||||
@ -1216,6 +1232,7 @@ Volume::_DomainEntryCreated(PackageDomain* domain, dev_t deviceID,
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
VolumeWriteLocker volumeLocker(this);
|
VolumeWriteLocker volumeLocker(this);
|
||||||
domain->AddPackage(package);
|
domain->AddPackage(package);
|
||||||
|
|
||||||
@ -1244,6 +1261,7 @@ Volume::_DomainEntryRemoved(PackageDomain* domain, dev_t deviceID,
|
|||||||
BReference<Package> packageReference(package);
|
BReference<Package> packageReference(package);
|
||||||
|
|
||||||
// remove the package
|
// remove the package
|
||||||
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
VolumeWriteLocker volumeLocker(this);
|
VolumeWriteLocker volumeLocker(this);
|
||||||
_RemovePackageContent(package, NULL, true);
|
_RemovePackageContent(package, NULL, true);
|
||||||
domain->RemovePackage(package);
|
domain->RemovePackage(package);
|
||||||
@ -1388,12 +1406,12 @@ Volume::_AddPackageLinksDirectory()
|
|||||||
NodeWriteLocker rootDirectoryWriteLocker(fRootDirectory);
|
NodeWriteLocker rootDirectoryWriteLocker(fRootDirectory);
|
||||||
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
||||||
|
|
||||||
packageLinksDirectory->SetID(fNextNodeID++);
|
|
||||||
packageLinksDirectory->SetParent(fRootDirectory);
|
packageLinksDirectory->SetParent(fRootDirectory);
|
||||||
|
|
||||||
fRootDirectory->AddChild(packageLinksDirectory);
|
fRootDirectory->AddChild(packageLinksDirectory);
|
||||||
fNodes.Insert(packageLinksDirectory);
|
|
||||||
packageLinksDirectory->AcquireReference();
|
_AddPackageLinksNode(packageLinksDirectory);
|
||||||
|
|
||||||
|
packageLinksDirectory->SetListener(this);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1410,7 +1428,54 @@ Volume::_RemovePackageLinksDirectory()
|
|||||||
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
|
||||||
|
|
||||||
if (packageLinksDirectory->Parent() == fRootDirectory) {
|
if (packageLinksDirectory->Parent() == fRootDirectory) {
|
||||||
_RemoveNode(packageLinksDirectory);
|
packageLinksDirectory->SetListener(NULL);
|
||||||
|
_RemovePackageLinksNode(packageLinksDirectory);
|
||||||
packageLinksDirectory->SetParent(NULL);
|
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 "Node.h"
|
||||||
#include "PackageDomain.h"
|
#include "PackageDomain.h"
|
||||||
|
#include "PackageLinksListener.h"
|
||||||
|
|
||||||
|
|
||||||
class Directory;
|
class Directory;
|
||||||
@ -32,7 +33,8 @@ enum MountType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Volume : public DoublyLinkedListLinkImpl<Volume> {
|
class Volume : public DoublyLinkedListLinkImpl<Volume>,
|
||||||
|
private PackageLinksListener {
|
||||||
public:
|
public:
|
||||||
Volume(fs_volume* fsVolume);
|
Volume(fs_volume* fsVolume);
|
||||||
~Volume();
|
~Volume();
|
||||||
@ -72,6 +74,13 @@ public:
|
|||||||
|
|
||||||
status_t AddPackageDomain(const char* path);
|
status_t AddPackageDomain(const char* path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// PackageLinksListener
|
||||||
|
virtual void PackageLinkDirectoryAdded(
|
||||||
|
PackageLinkDirectory* directory);
|
||||||
|
virtual void PackageLinkDirectoryRemoved(
|
||||||
|
PackageLinkDirectory* directory);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Job;
|
struct Job;
|
||||||
struct AddPackageDomainJob;
|
struct AddPackageDomainJob;
|
||||||
@ -147,6 +156,10 @@ private:
|
|||||||
|
|
||||||
status_t _AddPackageLinksDirectory();
|
status_t _AddPackageLinksDirectory();
|
||||||
void _RemovePackageLinksDirectory();
|
void _RemovePackageLinksDirectory();
|
||||||
|
void _AddPackageLinksNode(Node* node);
|
||||||
|
void _RemovePackageLinksNode(Node* node);
|
||||||
|
|
||||||
|
inline Volume* _SystemVolumeIfNotSelf() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable rw_lock fLock;
|
mutable rw_lock fLock;
|
||||||
|
Loading…
Reference in New Issue
Block a user