diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-06-21 21:49:09 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-06-30 21:33:46 +0900 |
commit | 409442c1ea8f167485642fbdb3494ff58900966f (patch) | |
tree | 350b10883cbcabf5c46beea5405b5a5a7b8786ac /kdesktop/lockeng.h | |
parent | a3f0904f6aac929e3c8616ab769c062c24714648 (diff) | |
download | tdebase-409442c1ea8f167485642fbdb3494ff58900966f.tar.gz tdebase-409442c1ea8f167485642fbdb3494ff58900966f.zip |
kdesktop: fix deadlock condition between kdesktop and kdesktop lock.
The logic to handle communication with kdesktop_lock is now running
completely in a separate thread and event loop, meaning the main GUI
thread remains responsive all the time and can handle interaction with
X11, DCOP and DBUS calls. This resolves issue #589.
The commit also solves the first problem reported in issue #640 and
loosely related to PR #526.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'kdesktop/lockeng.h')
-rw-r--r-- | kdesktop/lockeng.h | 162 |
1 files changed, 92 insertions, 70 deletions
diff --git a/kdesktop/lockeng.h b/kdesktop/lockeng.h index d9285abc1..94d8f9e44 100644 --- a/kdesktop/lockeng.h +++ b/kdesktop/lockeng.h @@ -1,6 +1,5 @@ -//=========================================================================== // -// This file is part of the KDE project +// This file is part of the TDE project // // Copyright (c) 1999 Martin R. Jones <mjones@kde.org> // @@ -8,7 +7,6 @@ #ifndef __LOCKENG_H__ #define __LOCKENG_H__ -#include <tqwidget.h> #include <tqthread.h> #include <tdeprocess.h> #include <tqvaluevector.h> @@ -23,31 +21,48 @@ class TDECryptographicCardDevice; #else #define TDECryptographicCardDevice void #endif + +/** + * Screen saver engine. Handles communication with the lock process. + * The engine is split into two parts, the 'SaverEngine' running in the GUI thread and + * the 'SaverEngineEventHandler' running in a separate thread and eventloop. + * The 'SaverEngine' handles communication with X11, DCOP and DBUS while the + * 'SaverEngineEventHandler' handles communication with the actual lock process. + * Several actions require cooperation of the two parts, so in various methods + * there will be inter-thread calls (using timers or by emitting signals) to + * trigger the other side remaining logic. + * This complex design is necessary to avoid blocking the main GUI application event loop, + * which has several tasks to manage and therefore can't affort to wait in a suspended state. + * This was previously leading to deadlock when DCOP calls where executed on the secondary + * thread/eventloop, for example when changing desktop while the lock process was restarting. + */ + class DCOPClientTransaction; class TQT_DBusMessage; class TQT_DBusProxy; +class SaverEngineEventHandler; -class SaverEngineThreadHelperObject : public TQObject +// Type of lock screen +enum LockType : int { - TQ_OBJECT - -public slots: - void terminateThread(); - void slotLockProcessWaiting(); - void slotLockProcessFullyActivated(); + DontLock = 0, + DefaultLock, + ForceLock, + SecureDialog +}; -signals: - void lockProcessWaiting(); - void lockProcessFullyActivated(); +enum SaverState +{ + Waiting, + Preparing, + Engaging, + Saving }; -//=========================================================================== -/** - * Screen saver engine. Handles screensaver window, starting screensaver - * hacks, and password entry. - */ -class SaverEngine : public TQWidget, public KScreensaverIface +class SaverEngine : public TQObject, public KScreensaverIface { + friend class SaverEngineEventHandler; + TQ_OBJECT public: SaverEngine(); @@ -100,80 +115,53 @@ public: */ virtual void saverLockReady(); - /** - * @internal - */ void lockScreen(bool DCOP = false); - /** - * Called by KDesktop to wait for saver engage - * @internal - */ - bool waitForLockEngage(); - - /** - * @internal - */ void lockScreenAndDoNewSession(); - - /** - * @internal - */ void lockScreenAndSwitchSession(int vt); + void enableExports(); // Enable wallpaper exports + signals: - void terminateHelperThread(); - void asyncLock(); + void activateSaverOrLockSignal(LockType lock_type); + void lockScreenSignal(bool); + void terminateEventHandlerThread(); public slots: - void slotLockProcessReady(); - void lockProcessWaiting(); - void lockProcessFullyActivated(); void handleDBusSignal(const TQT_DBusMessage&); + void terminateTDESession(); protected slots: void idleTimeout(); - void lockProcessExited(); private slots: - void handleSecureDialog(); - void slotSAKProcessExited(); - void cryptographicCardInserted(TDECryptographicCardDevice*); void cryptographicCardRemoved(TDECryptographicCardDevice*); - - /** - * Enable wallpaper exports - */ - void enableExports(); - void recoverFromHackingAttempt(); void cardStartupTimeout(); - bool dBusReconnect(); + // The following slots are invoked by corresponding methods named without the 'GUI' suffix + // in 'SaverEngineEventHandler' to complete the remaining X11 part of the actions + void activateSaverOrLockGUI(); + void lockProcessFullyActivatedGUI(); + void lockProcessWaitingGUI(); + void lockScreenGUI(); + void stopLockProcessGUI(); + private: - bool restartDesktopLockProcess(); void dBusClose(); bool dBusConnect(); void onDBusServiceRegistered(const TQString&); void onDBusServiceUnregistered(const TQString&); protected: - enum SaverState { Waiting, Preparing, Engaging, Saving }; - enum LockType { DontLock, DefaultLock, ForceLock, SecureDialog }; - bool startLockProcess( LockType lock_type ); - bool waitForLockProcessStart(); - void stopLockProcess(); - bool handleKeyPress(XKeyEvent *xke); void processLockTransactions(); xautolock_corner_t applyManualSettings(int); protected: bool mEnabled; - SaverState mState; XAutoLock *mXAutoLock; - TDEProcess mLockProcess; int mTimeout; // the original X screensaver parameters @@ -182,26 +170,60 @@ protected: int mXBlanking; int mXExposures; - bool mBlankOnly; // only use the blanker, not the defined saver TQValueVector< DCOPClientTransaction* > mLockTransactions; public: - SaverEngineThreadHelperObject* m_threadHelperObject; + bool mBlankOnly; // only use the blanker, not the defined saver // protected + SaverEngineEventHandler *m_saverEngineEventHandler; private: - TQEventLoopThread* m_helperThread; - sigset_t mThreadBlockSet; - TDEProcess* mSAKProcess; - bool mTerminationRequested; - bool mSaverProcessReady; + TQEventLoopThread* m_eventHandlerThread; bool mNewVTAfterLockEngage; bool mValidCryptoCardInserted; int mSwitchVTAfterLockEngage; struct sigaction mSignalAction; TQT_DBusConnection dBusConn; - TQT_DBusProxy* dBusLocal; - TQT_DBusProxy* dBusWatch; - TQT_DBusProxy* systemdSession; + TQT_DBusProxy *dBusLocal; + TQT_DBusProxy *dBusWatch; + TQT_DBusProxy *systemdSession; +}; + +class SaverEngineEventHandler : public TQObject +{ + TQ_OBJECT + +public: + SaverEngineEventHandler(SaverEngine *engine); + + SaverState getState() const { return m_state; } + + void lockProcessExited(); + void lockProcessFullyActivated(); + void lockProcessReady(); + void terminateLockProcess(); + +public slots: + bool activateSaverOrLock(LockType lock_type); + void lockScreen(bool DCOP = false); + bool restartLockProcess(); + void saveScreen(); + void stopLockProcess(); + void terminateThread(); + +protected slots: + void slotLockProcessExited(); + void slotSAKProcessExited(); + +protected: + void startSAKProcess(); + + bool m_saverProcessReady; + bool m_lockProcessRestarting; + bool m_terminationRequest; + SaverState m_state; + SaverEngine *m_saverEngine; + TDEProcess *m_SAKProcess; + TDEProcess m_lockProcess; }; #endif |