File indexing completed on 2024-06-23 04:38:06

0001 // SPDX-FileCopyrightText: 2020 Henri Chain <henri.chain@enioka.com>
0002 // SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com>
0003 //
0004 // SPDX-License-Identifier: LGPL-2.1-or-later
0005 
0006 #ifndef KAPPLICATIONSCOPE_H
0007 #define KAPPLICATIONSCOPE_H
0008 #include "kcgroups_export.h"
0009 #include "optionalgadget.h"
0010 #include <QObject>
0011 
0012 class KApplicationScopePrivate;
0013 
0014 OPTIONAL_GADGET(qulonglong, OptionalQULongLong);
0015 
0016 /**
0017  * @brief A desktop application in a systemd transient scope
0018  */
0019 class KCGROUPS_EXPORT KApplicationScope : public QObject
0020 {
0021     Q_OBJECT
0022 
0023     /**
0024      * @brief the dbus path of the application. Same as constructor parameter. Read-only, constant
0025      * @accessors path()
0026      */
0027     Q_PROPERTY(QString path READ path CONSTANT)
0028 
0029     /**
0030      * @brief the systemd unit id. Read-only. Will be set asynchronously if not specified in constructor.
0031      * @accessors id()
0032      * @notifySignal idChanged()
0033      */
0034     Q_PROPERTY(QString id READ id NOTIFY idChanged)
0035 
0036     /**
0037      * @brief file path of the control group in /sys/fs/cgroup
0038      * @accessors cgroup()
0039      * @notifySignal cgroupChanged()
0040      */
0041     Q_PROPERTY(QString cgroup READ cgroup NOTIFY cgroupChanged)
0042 
0043     /**
0044      * @brief the systemd unit description. Read-only.
0045      * @accessors description()
0046      * @notifySignal descriptionChanged()
0047      */
0048     Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
0049 
0050     /**
0051      * @brief the .desktop application name. Read-only.
0052      * @accessors desktopName()
0053      * @notifySignal desktopNameChanged()
0054      */
0055     Q_PROPERTY(QString desktopName READ desktopName NOTIFY desktopNameChanged)
0056 
0057     /**
0058      * @brief the application .desktop file if available. Read-only.
0059      * @accessors desktopFilePath()
0060      * @notifySignal desktopFilePathChanged()
0061      */
0062     Q_PROPERTY(QString desktopFilePath READ desktopFilePath NOTIFY desktopFilePathChanged)
0063 
0064     /**
0065      * @brief the app instance random identifier. Can be empty if this is a singleton application.
0066      * @accessors instance()
0067      * @notifySignal instanceChanged()
0068      */
0069     Q_PROPERTY(QString instance READ instance NOTIFY instanceChanged)
0070 
0071     /**
0072      * @brief code of the last error that occurred (NoError if none)
0073      * @accessors lastError()
0074      * @notifySignal errorOccurred()
0075      */
0076     Q_PROPERTY(ErrorCode lastError READ lastError NOTIFY errorOccurred)
0077 
0078     /**
0079      * @brief cpu quota for cpu controller, in microseconds per second (1000000 means 100%). Can be unset
0080      * @accessors cpuQuota(), setCpuQuota()
0081      * @notifySignal cpuQuotaChanged()
0082      */
0083     Q_PROPERTY(OptionalQULongLong cpuQuota READ cpuQuota WRITE setCpuQuota NOTIFY cpuQuotaChanged)
0084 
0085     /**
0086      * @brief duration in micoseconds over which the CPU time quota is measured. (default when unset is 100ms)
0087      * @accessors cpuQuotaPeriod(), setCpuQuotaPeriod()
0088      * @notifySignal cpuQuotaPeriodChanged()
0089      */
0090     Q_PROPERTY(OptionalQULongLong cpuQuotaPeriod READ cpuQuotaPeriod WRITE setCpuQuotaPeriod NOTIFY cpuQuotaPeriodChanged)
0091 
0092     /**
0093      * @brief cpu time weight. Between 1 and 10000. Defaults to 100.
0094      * @accessors cpuQuotaPeriod(), setCpuQuotaPeriod()
0095      * @notifySignal cpuQuotaPeriodChanged()
0096      */
0097     Q_PROPERTY(OptionalQULongLong cpuWeight READ cpuWeight WRITE setCpuWeight NOTIFY cpuWeightChanged)
0098 
0099     /**
0100      * @brief Overall block I/O weight. Between 1 and 10000. Defaults to 100.
0101      * @accessors ioWeight(), setIoWeight()
0102      * @notifySignal ioWeightChanged()
0103      */
0104     Q_PROPERTY(OptionalQULongLong ioWeight READ ioWeight WRITE setIoWeight NOTIFY ioWeightChanged)
0105 
0106     /**
0107      * @brief best-effort memory usage protection (in bytes) of all executed processes within the application.
0108      * @accessors memoryLow(), setMemoryLow()
0109      * @notifySignal memoryLowChanged()
0110      */
0111     Q_PROPERTY(OptionalQULongLong memoryLow READ memoryLow WRITE setMemoryLow NOTIFY memoryLowChanged)
0112 
0113     /**
0114      * @brief throttling limit on memory usage (in bytes) of all executed processes within the application.
0115      * @accessors memoryHigh(), setMemoryHigh()
0116      * @notifySignal memoryHighChanged()
0117      */
0118     Q_PROPERTY(OptionalQULongLong memoryHigh READ memoryHigh WRITE setMemoryHigh NOTIFY memoryHighChanged)
0119 
0120     /**
0121      * @brief memory usage protection (in bytes) of all executed processes within the application.
0122      * @accessors memoryMin(), setMemoryMin()
0123      * @notifySignal memoryMinChanged()
0124      */
0125     Q_PROPERTY(OptionalQULongLong memoryMin READ memoryMin WRITE setMemoryMin NOTIFY memoryMinChanged)
0126 
0127     /**
0128      * @brief absolute limit on memory usage (in bytes) of all executed processes within the application.
0129      * @accessors memoryMax(), setMemoryMax()
0130      * @notifySignal memoryMaxChanged()
0131      */
0132     Q_PROPERTY(OptionalQULongLong memoryMax READ memoryMax WRITE setMemoryMax NOTIFY memoryMaxChanged)
0133 
0134     /**
0135      * @brief absolute limit on swap usage (in bytes) of all executed processes within the application.
0136      * @accessors memorySwapMax(), setMemorySwapMax()
0137      * @notifySignal memorySwapMaxChanged()
0138      */
0139     Q_PROPERTY(OptionalQULongLong memorySwapMax READ memorySwapMax WRITE setMemorySwapMax NOTIFY memorySwapMaxChanged)
0140 
0141 public:
0142     /**
0143      * @brief The types of errors that can occur
0144      */
0145     enum ErrorCode {
0146         /**
0147          * Default value. No error has occurred
0148          */
0149         NoError,
0150 
0151         /**
0152          * A property set operation failed
0153          */
0154         SetFailedError,
0155 
0156         /**
0157          * Initial loading of property values failed
0158          */
0159         CacheFillError,
0160 
0161         /**
0162          * Error during stop() operation
0163          */
0164         StopFailedError
0165     };
0166     Q_ENUM(ErrorCode)
0167 
0168     /**
0169      * @brief Use when only path is known. Incurs an extra DBus call to get unit id.
0170      * @param path: dbus path of the application
0171      * @param parent: parent QObject
0172      */
0173     explicit KApplicationScope(const QString &path, QObject *parent = nullptr);
0174 
0175     /**
0176      * @brief Use when unit id is known in advance (such as when using KApplicationScopeLister)
0177      * @param path: dbus path of the application
0178      * @param id: systemd unit id
0179      * @param parent: parent QObject
0180      */
0181     explicit KApplicationScope(const QString &path, const QString &id, QObject *parent = nullptr);
0182 
0183     /**
0184      * @brief Use when only PID is known
0185      * @param pid: process ID
0186      * @param parent: parent QObject
0187      * @return a new KApplicationScope, or null in case of failure (such as if process is not managed by systemd)
0188      */
0189     static KApplicationScope *fromPid(uint pid, QObject *parent = nullptr);
0190 
0191     ~KApplicationScope() override;
0192 
0193     QString path() const;
0194     QString id() const;
0195     QString cgroup() const;
0196     QString description() const;
0197     QString desktopName() const;
0198     QString desktopFilePath() const;
0199     QString instance() const;
0200     ErrorCode lastError() const;
0201 
0202     OptionalQULongLong cpuQuota() const;
0203     OptionalQULongLong cpuQuotaPeriod() const;
0204     OptionalQULongLong cpuWeight() const;
0205     OptionalQULongLong ioWeight() const;
0206     OptionalQULongLong memoryLow() const;
0207     OptionalQULongLong memoryHigh() const;
0208     OptionalQULongLong memoryMin() const;
0209     OptionalQULongLong memoryMax() const;
0210     OptionalQULongLong memorySwapMax() const;
0211 
0212 Q_SIGNALS:
0213     /**
0214      * @brief emitted after loading when id is not known at constructor time
0215      * @param id: the systemd unit id
0216      */
0217     void idChanged(const QString &id);
0218 
0219     /**
0220      * @brief emitted when cgroup has been loaded asynchronously
0221      * @param cgroup: the filesystem cgroup path
0222      */
0223     void cgroupChanged(const QString &cgroup);
0224 
0225     /**
0226      * @brief emitted when description has been loaded asynchronously
0227      * @param description: the systemd unit desciption
0228      */
0229     void descriptionChanged(const QString &description);
0230 
0231     /**
0232      * @brief emitted when .desktop name has been loaded asynchronously
0233      * @param description: the .desktop application name
0234      */
0235     void desktopNameChanged(const QString &desktopName);
0236 
0237     /**
0238      * @brief emitted when .desktop file path has been loaded asynchronously
0239      * @param description: the .desktop file path
0240      */
0241     void desktopFilePathChanged(const QString &desktopFilePath);
0242 
0243     /**
0244      * @brief emitted when the instance random identifier has been loaded asynchronously
0245      * @param description: the instance random identifier
0246      */
0247     void instanceChanged(const QString &instance);
0248 
0249     /**
0250      * @brief emitted when there is an error setting or getting a value
0251      * @param lastError: the error code
0252      */
0253     void errorOccurred(KApplicationScope::ErrorCode lastError);
0254 
0255     /**
0256      * @brief emitted when any cgroup resource property has changed
0257      * @param propertyName: the systemd name of the property
0258      */
0259     void propertyChanged(const QString &propertyName);
0260 
0261     /**
0262      * @brief emitted when the cpu quota has changed
0263      * @param quota: the new quota value
0264      */
0265     void cpuQuotaChanged(const OptionalQULongLong &quota);
0266 
0267     /**
0268      * @brief emitted when the cpu quota period has changed
0269      * @param period: the new period value
0270      */
0271     void cpuQuotaPeriodChanged(const OptionalQULongLong &period);
0272 
0273     /**
0274      * @brief emitted when the cpu weight has changed
0275      * @param weight: the new weight value
0276      */
0277     void cpuWeightChanged(const OptionalQULongLong &weight);
0278 
0279     /**
0280      * @brief emitted when the io weight has changed
0281      * @param weight: the new weight value
0282      */
0283     void ioWeightChanged(const OptionalQULongLong &weight);
0284 
0285     /**
0286      * @brief emitted when memoryLow has changed
0287      * @param memoryLow: the new memoryLow value
0288      */
0289     void memoryLowChanged(const OptionalQULongLong &memoryLow);
0290 
0291     /**
0292      * @brief emitted when memoryHigh has changed
0293      * @param memoryHigh: the new memoryHigh value
0294      */
0295     void memoryHighChanged(const OptionalQULongLong &memoryHigh);
0296 
0297     /**
0298      * @brief emitted when memoryMin has changed
0299      * @param memoryMin: the new memoryMin value
0300      */
0301     void memoryMinChanged(const OptionalQULongLong &memoryMin);
0302 
0303     /**
0304      * @brief emitted when memoryMax has changed
0305      * @param memoryMax: the new memoryMax value
0306      */
0307     void memoryMaxChanged(const OptionalQULongLong &memoryMax);
0308 
0309     /**
0310      * @brief emitted when memorySwapMax has changed
0311      * @param memorySwapMax: the new memorySwapMax value
0312      */
0313     void memorySwapMaxChanged(const OptionalQULongLong &memorySwapMax);
0314 
0315 public Q_SLOTS:
0316     /**
0317      * @brief Stops the application
0318      */
0319     void stop();
0320 
0321     /**
0322      * @brief set cpuQuota
0323      * @param quota: value to set
0324      */
0325     void setCpuQuota(const OptionalQULongLong &quota);
0326 
0327     /**
0328      * @brief set cpuQuotaPeriod
0329      * @param period: value to set
0330      */
0331     void setCpuQuotaPeriod(const OptionalQULongLong &period);
0332 
0333     /**
0334      * @brief set cpuWeight
0335      * @param weight: value to set
0336      */
0337     void setCpuWeight(const OptionalQULongLong &weight);
0338 
0339     /**
0340      * @brief set ioWeight
0341      * @param weight: value to set
0342      */
0343     void setIoWeight(const OptionalQULongLong &weight);
0344 
0345     /**
0346      * @brief set memoryLow
0347      * @param memoryLow: value to set
0348      */
0349     void setMemoryLow(const OptionalQULongLong &memoryLow);
0350 
0351     /**
0352      * @brief set memoryHigh
0353      * @param memoryHigh: value to set
0354      */
0355     void setMemoryHigh(const OptionalQULongLong &memoryHigh);
0356 
0357     /**
0358      * @brief set memoryMin
0359      * @param memoryMin: value to set
0360      */
0361     void setMemoryMin(const OptionalQULongLong &memoryMin);
0362 
0363     /**
0364      * @brief set memoryMax
0365      * @param memoryMax: value to set
0366      */
0367     void setMemoryMax(const OptionalQULongLong &memoryMax);
0368 
0369     /**
0370      * @brief set memorySwapMax
0371      * @param memorySwapMax: value to set
0372      */
0373     void setMemorySwapMax(const OptionalQULongLong &memorySwapMax);
0374 
0375 private:
0376     KApplicationScopePrivate *const d_ptr;
0377 };
0378 
0379 #endif // KAPPLICATIONSCOPE_H