2 * Copyright 2013-2014, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Ingo Weinhold <ingo_weinhold@gmx.de>
17 #include <package/ActivationTransaction.h>
18 #include <package/DaemonClient.h>
19 #include <package/packagefs.h>
20 #include <util/DoublyLinkedList.h>
29 // A Volume object is accessed by two threads:
30 // 1. The application thread: initially (c'tor and Init()) and when handling a
31 // location info request (HandleGetLocationInfoRequest()).
32 // 2. The corresponding Root object's job thread (any other operation).
34 // The only thread synchronization needed is for the status information accessed
35 // by HandleGetLocationInfoRequest() and modified by the job thread. The data
36 // are encapsulated in a VolumeState, which is protected by Volume::fLock. The
37 // lock must be held by the app thread when accessing the data (it reads only)
38 // and by the job thread when modifying the data (not needed when reading).
41 using BPackageKit::BPrivate::BActivationTransaction
;
42 using BPackageKit::BPrivate::BDaemonClient
;
46 class CommitTransactionHandler
;
47 class PackageFileManager
;
51 namespace BPackageKit
{
53 class BSolverRepository
;
56 using BPackageKit::BPackageInstallationLocation
;
57 using BPackageKit::BSolver
;
58 using BPackageKit::BSolverRepository
;
61 class Volume
: public BHandler
{
66 Volume(BLooper
* looper
);
69 status_t
Init(const node_ref
& rootDirectoryRef
,
70 node_ref
& _packageRootRef
);
71 status_t
InitPackages(Listener
* listener
);
73 status_t
AddPackagesToRepository(
74 BSolverRepository
& repository
,
76 void InitialVerify(Volume
* nextVolume
,
77 Volume
* nextNextVolume
);
78 void HandleGetLocationInfoRequest(BMessage
* message
);
79 void HandleCommitTransactionRequest(
82 void PackageJobPending();
83 void PackageJobFinished();
84 bool IsPackageJobPending() const;
88 virtual void MessageReceived(BMessage
* message
);
90 const BString
& Path() const
92 PackageFSMountType
MountType() const
93 { return fMountType
; }
94 BPackageInstallationLocation
Location() const;
96 const node_ref
& RootDirectoryRef() const
97 { return fRootDirectoryRef
; }
98 dev_t
DeviceID() const
99 { return fRootDirectoryRef
.device
; }
100 ino_t
RootDirectoryID() const
101 { return fRootDirectoryRef
.node
; }
103 const node_ref
& PackagesDirectoryRef() const;
104 dev_t
PackagesDeviceID() const
105 { return PackagesDirectoryRef().device
; }
106 ino_t
PackagesDirectoryID() const
107 { return PackagesDirectoryRef().node
; }
109 Root
* GetRoot() const
111 void SetRoot(Root
* root
)
114 int64
ChangeCount() const
115 { return fChangeCount
; }
117 PackageFileNameHashTable::Iterator
PackagesByFileNameIterator()
120 int OpenRootDirectory() const;
122 void ProcessPendingNodeMonitorEvents();
124 bool HasPendingPackageActivationChanges() const;
125 void ProcessPendingPackageActivationChanges();
126 void ClearPackageActivationChanges();
127 const PackageSet
& PackagesToBeActivated() const
128 { return fPackagesToBeActivated
; }
129 const PackageSet
& PackagesToBeDeactivated() const
130 { return fPackagesToBeDeactivated
; }
132 status_t
CreateTransaction(
133 BPackageInstallationLocation location
,
134 BActivationTransaction
& _transaction
,
135 BDirectory
& _transactionDirectory
);
136 void CommitTransaction(
137 const BActivationTransaction
& transaction
,
138 const PackageSet
& packagesAlreadyAdded
,
139 const PackageSet
& packagesAlreadyRemoved
,
140 BCommitTransactionResult
& _result
);
143 struct NodeMonitorEvent
;
144 struct PackagesDirectory
;
146 typedef FSUtils::RelativePath RelativePath
;
147 typedef DoublyLinkedList
<NodeMonitorEvent
> NodeMonitorEventList
;
150 void _HandleEntryCreatedOrRemoved(
151 const BMessage
* message
, bool created
);
152 void _HandleEntryMoved(const BMessage
* message
);
153 void _QueueNodeMonitorEvent(const BString
& name
,
156 void _PackagesEntryCreated(const char* name
);
157 void _PackagesEntryRemoved(const char* name
);
159 status_t
_ReadPackagesDirectory();
160 status_t
_InitLatestState();
161 status_t
_InitLatestStateFromActivatedPackages();
162 status_t
_GetActivePackages(int fd
);
163 void _RunQueuedScripts();
164 bool _CheckActivePackagesMatchLatestState(
165 PackageFSGetPackageInfosRequest
* request
);
166 void _SetLatestState(VolumeState
* state
,
168 void _DumpState(VolumeState
* state
);
170 status_t
_AddRepository(BSolver
* solver
,
171 BSolverRepository
& repository
,
172 bool activeOnly
, bool installed
);
174 status_t
_OpenPackagesSubDirectory(
175 const RelativePath
& path
, bool create
,
176 BDirectory
& _directory
);
178 void _CommitTransaction(BMessage
* message
,
179 const BActivationTransaction
* transaction
,
180 const PackageSet
& packagesAlreadyAdded
,
181 const PackageSet
& packagesAlreadyRemoved
,
182 BCommitTransactionResult
& _result
);
186 PackageFSMountType fMountType
;
187 node_ref fRootDirectoryRef
;
188 PackagesDirectory
* fPackagesDirectories
;
189 uint32 fPackagesDirectoryCount
;
192 PackageFileManager
* fPackageFileManager
;
193 VolumeState
* fLatestState
;
194 VolumeState
* fActiveState
;
197 BLocker fPendingNodeMonitorEventsLock
;
198 NodeMonitorEventList fPendingNodeMonitorEvents
;
199 bigtime_t fNodeMonitorEventHandleTime
;
200 PackageSet fPackagesToBeActivated
;
201 PackageSet fPackagesToBeDeactivated
;
202 BMessage fLocationInfoReply
;
203 // only accessed in the application thread
204 int32 fPendingPackageJobCount
;
208 class Volume::Listener
{
212 virtual void VolumeNodeMonitorEventOccurred(Volume
* volume
)