File indexing completed on 2024-04-28 05:45:18

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Frank Reininghaus <frank78ac@googlemail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef MOUNTPOINTOBSERVER_H
0008 #define MOUNTPOINTOBSERVER_H
0009 
0010 #include <KIO/Job>
0011 
0012 #include <QObject>
0013 #include <QUrl>
0014 
0015 /**
0016  * A MountPointObserver can be used to determine the free space on a mount
0017  * point. It will then check the free space periodically, and emit the signal
0018  * spaceInfoChanged() if the return value of spaceInfo() has changed.
0019  *
0020  * Since multiple users which watch paths on the same mount point can share
0021  * a MountPointObserver, it is not possible to create a MountPointObserver
0022  * manually. Instead, the function observerForPath(QString&) should be called,
0023  * which returns either an existing or a newly created MountPointObserver for
0024  * the mount point where the path is mounted. observerForPath(QString&) looks
0025  * for a suitable MountPointObserver in an internal cache and creates new
0026  * MountPointObservers and adds them to the cache if necessary.
0027  *
0028  * Reference counting is used to keep track of the number of users, and to
0029  * decide when the object can be deleted. A user of this class should call
0030  * the method ref() when it starts using it, and deref() when it does not need
0031  * the MountPointObserver any more.
0032  *
0033  * The object will not be deleted immediately if the reference count reaches
0034  * zero. The object will only be destroyed when the next periodic update of
0035  * the free space information happens, and the reference count is still zero.
0036  * This approach makes it possible to re-use the object if a new user requests
0037  * the free space for the same mount point before the next update.
0038  */
0039 class MountPointObserver : public QObject
0040 {
0041     Q_OBJECT
0042 
0043     explicit MountPointObserver(const QUrl &url, QObject *parent = nullptr);
0044     ~MountPointObserver() override
0045     {
0046     }
0047 
0048 public:
0049     /**
0050      * Call this function to indicate that the caller intends to continue using this object. An
0051      * internal reference count is increased then. When the observer is not needed any more,
0052      * deref() should be called, which decreases the reference count again.
0053      */
0054     void ref()
0055     {
0056         ++m_referenceCount;
0057     }
0058 
0059     /**
0060      * This function can be used to indicate that the caller does not need this MountPointObserver
0061      * any more. Internally, a reference count is decreased. If the reference count is zero while
0062      * update() is called, the object deletes itself.
0063      */
0064     void deref()
0065     {
0066         --m_referenceCount;
0067         Q_ASSERT(m_referenceCount >= 0);
0068     }
0069 
0070     /**
0071      * Returns a MountPointObserver for the given \a url. If the caller intends to continue using
0072      * the returned object, it must call its ref() method.
0073      */
0074     static MountPointObserver *observerForUrl(const QUrl &url);
0075 
0076 Q_SIGNALS:
0077     /**
0078      * This signal is emitted when the size has been retrieved.
0079      */
0080     void spaceInfoChanged(quint64 size, quint64 available);
0081 
0082 public Q_SLOTS:
0083     /**
0084      * If this slot is invoked, MountPointObserver starts a new driveSize job
0085      * to get the drive's size.
0086      */
0087     void update();
0088 
0089 private Q_SLOTS:
0090     void freeSpaceResult(KJob *job);
0091 
0092 private:
0093     const QUrl m_url;
0094     int m_referenceCount;
0095 
0096     friend class MountPointObserverCache;
0097 };
0098 
0099 #endif