diff options
author | Timothy Pearson <[email protected]> | 2013-04-06 20:48:44 -0500 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2013-04-06 20:48:44 -0500 |
commit | dc41de959b6b76263f8640c4075a6ed5b873b722 (patch) | |
tree | 1077a521b7adde84677d190f81f17e581dbb80ac | |
parent | 65ea5f153b83d2a30c667ac8b32708309c7ed173 (diff) | |
download | tdebase-dc41de959b6b76263f8640c4075a6ed5b873b722.tar.gz tdebase-dc41de959b6b76263f8640c4075a6ed5b873b722.zip |
Use threading and select instead of busywaiting on the lock control socket
This resolves the remainder of Bug 690
-rw-r--r-- | kdesktop/lock/lockprocess.cc | 314 | ||||
-rw-r--r-- | kdesktop/lock/lockprocess.h | 32 | ||||
-rw-r--r-- | tdm/kfrontend/kgapp.cpp | 5 | ||||
-rw-r--r-- | tdm/kfrontend/kgapp.h | 1 | ||||
-rw-r--r-- | tdm/kfrontend/kgreeter.cpp | 2 | ||||
-rw-r--r-- | tdm/kfrontend/sakdlg.cc | 2 |
6 files changed, 219 insertions, 137 deletions
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index ac70def46..8d840983e 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -237,7 +237,6 @@ LockProcess::LockProcess() #endif setupSignals(); - setupPipe(); // Signal that we want to be transparent to the desktop, not to windows behind us... Atom kde_wm_transparent_to_desktop; @@ -310,6 +309,11 @@ LockProcess::LockProcess() // LockProcess::~LockProcess() { + mControlPipeHandlerThread->terminate(); + mControlPipeHandlerThread->wait(); + delete mControlPipeHandler; +// delete mControlPipeHandlerThread; + if (resizeTimer != NULL) { resizeTimer->stop(); delete resizeTimer; @@ -404,6 +408,14 @@ void LockProcess::init(bool child, bool useBlankOnly) mHackStartupEnabled = trinity_desktop_lock_use_system_modal_dialogs?KDesktopSettings::screenSaverEnabled():true; configure(); + + mControlPipeHandlerThread = new TQEventLoopThread(); + mControlPipeHandler = new ControlPipeHandlerObject(); + mControlPipeHandler->mParent = this; + mControlPipeHandler->moveToThread(mControlPipeHandlerThread); + TQObject::connect(mControlPipeHandler, SIGNAL(processCommand(TQString)), this, SLOT(processInputPipeCommand(TQString))); + TQTimer::singleShot(0, mControlPipeHandler, SLOT(run())); + mControlPipeHandlerThread->start(); } static int signal_pipe[2]; @@ -466,135 +478,6 @@ void LockProcess::resizeEvent(TQResizeEvent *) // } -void LockProcess::setupPipe() -{ - /* Create the FIFOs if they do not exist */ - umask(0); - mkdir(FIFO_DIR,0644); - mknod(FIFO_FILE, S_IFIFO|0644, 0); - chmod(FIFO_FILE, 0644); - - mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); - if (mPipe_fd > -1) { - mPipeOpen = true; - TQTimer::singleShot( PIPE_CHECK_INTERVAL, this, TQT_SLOT(checkPipe()) ); - } - - mknod(FIFO_FILE_OUT, S_IFIFO|0600, 0); - chmod(FIFO_FILE_OUT, 0600); - - mPipe_fd_out = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK); - if (mPipe_fd_out > -1) { - mPipeOpen_out = true; - } -} - -void LockProcess::checkPipe() -{ - char readbuf[128]; - int numread; - TQString to_display; - const char * pin_entry; - - if (mPipeOpen == true) { - readbuf[0]=' '; - numread = read(mPipe_fd, readbuf, 128); - readbuf[numread] = 0; - if (numread > 0) { - if (readbuf[0] == 'C') { - mInfoMessageDisplayed=false; - while (mDialogControlLock == true) usleep(100000); - mDialogControlLock = true; - if (currentDialog != NULL) { - mForceReject = true; - closeCurrentWindow(); - } - mDialogControlLock = false; - } - if (readbuf[0] == 'T') { - to_display = readbuf; - to_display = to_display.remove(0,1); - // Lock out password dialogs and close any active dialog - mInfoMessageDisplayed=true; - while (mDialogControlLock == true) usleep(100000); - mDialogControlLock = true; - if (currentDialog != NULL) { - mForceReject = true; - closeCurrentWindow(); - } - mDialogControlLock = false; - // Display info message dialog - TQTimer::singleShot( PIPE_CHECK_INTERVAL, this, TQT_SLOT(checkPipe()) ); - InfoDlg inDlg( this ); - inDlg.updateLabel(to_display); - inDlg.setUnlockIcon(); - execDialog( &inDlg ); - mForceReject = false; - return; - } - if ((readbuf[0] == 'E') || (readbuf[0] == 'W') || (readbuf[0] == 'I') || (readbuf[0] == 'K')) { - to_display = readbuf; - to_display = to_display.remove(0,1); - // Lock out password dialogs and close any active dialog - mInfoMessageDisplayed=true; - while (mDialogControlLock == true) usleep(100000); - mDialogControlLock = true; - if (currentDialog != NULL) { - mForceReject = true; - closeCurrentWindow(); - } - mDialogControlLock = false; - // Display info message dialog - TQTimer::singleShot( PIPE_CHECK_INTERVAL, this, TQT_SLOT(checkPipe()) ); - InfoDlg inDlg( this ); - inDlg.updateLabel(to_display); - if (readbuf[0] == 'K') inDlg.setKDEIcon(); - if (readbuf[0] == 'I') inDlg.setInfoIcon(); - if (readbuf[0] == 'W') inDlg.setWarningIcon(); - if (readbuf[0] == 'E') inDlg.setErrorIcon(); - execDialog( &inDlg ); - mForceReject = false; - return; - } - if (readbuf[0] == 'Q') { - to_display = readbuf; - to_display = to_display.remove(0,1); - // Lock out password dialogs and close any active dialog - mInfoMessageDisplayed=true; - while (mDialogControlLock == true) usleep(100000); - mDialogControlLock = true; - if (currentDialog != NULL) { - mForceReject = true; - closeCurrentWindow(); - } - mDialogControlLock = false; - // Display query dialog - TQTimer::singleShot( PIPE_CHECK_INTERVAL, this, TQT_SLOT(checkPipe()) ); - QueryDlg qryDlg( this ); - qryDlg.updateLabel(to_display); - qryDlg.setUnlockIcon(); - mForceReject = false; - execDialog( &qryDlg ); - if (mForceReject == false) { - pin_entry = qryDlg.getEntry(); - mInfoMessageDisplayed=false; - if (mPipeOpen_out == true) { - if (write(mPipe_fd_out, pin_entry, strlen(pin_entry)+1) == -1) { - // Error handler to shut up gcc warnings - } - if (write(mPipe_fd_out, "\n\r", 3) == -1) { - // Error handler to shut up gcc warnings - } - } - } - mForceReject = false; - return; - } - } - TQTimer::singleShot( PIPE_CHECK_INTERVAL, this, TQT_SLOT(checkPipe()) ); - } -} - void LockProcess::setupSignals() { struct sigaction act; @@ -626,8 +509,7 @@ void LockProcess::setupSignals() if (pipe(signal_pipe) == -1) { // Error handler to shut up gcc warnings } - TQSocketNotifier* notif = new TQSocketNotifier(signal_pipe[0], - TQSocketNotifier::Read, TQT_TQOBJECT(this) ); + TQSocketNotifier* notif = new TQSocketNotifier(signal_pipe[0], TQSocketNotifier::Read, TQT_TQOBJECT(this) ); connect( notif, TQT_SIGNAL(activated(int)), TQT_SLOT(signalPipeSignal())); } @@ -1912,8 +1794,9 @@ bool LockProcess::checkPass() // Make sure we never launch the SAK or login dialog if windows are being closed down // Otherwise we can get stuck in an irrecoverable state where any attempt to show the login screen is instantly aborted - if (trinity_desktop_lock_closing_windows) + if (trinity_desktop_lock_closing_windows) { return 0; + } if (trinity_desktop_lock_use_sak) { // Verify SAK operational status @@ -2697,4 +2580,169 @@ void LockProcess::slotMouseActivity(XEvent *event) } } +void LockProcess::processInputPipeCommand(TQString inputcommand) { + TQCString command(inputcommand.ascii()); + TQString to_display; + const char * pin_entry; + + if (command[0] == 'C') { + while (mDialogControlLock == true) usleep(100000); + mDialogControlLock = true; + if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) { + if (currentDialog != NULL) { + mForceReject = true; + closeCurrentWindow(); + } + } + trinity_desktop_lock_closing_windows = false; + mInfoMessageDisplayed = false; + mDialogControlLock = false; + } + if (command[0] == 'T') { + to_display = command.data(); + to_display = to_display.remove(0,1); + // Lock out password dialogs and close any active dialog + while (mDialogControlLock == true) usleep(100000); + mDialogControlLock = true; + if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) { + if (currentDialog != NULL) { + mForceReject = true; + closeCurrentWindow(); + } + } + mInfoMessageDisplayed = true; + mDialogControlLock = false; + // Display info message dialog + InfoDlg inDlg( this ); + inDlg.updateLabel(to_display); + inDlg.setUnlockIcon(); + execDialog( &inDlg ); + mForceReject = false; + trinity_desktop_lock_closing_windows = false; + return; + } + if ((command[0] == 'E') || (command[0] == 'W') || (command[0] == 'I') || (command[0] == 'K')) { + to_display = command.data(); + to_display = to_display.remove(0,1); + // Lock out password dialogs and close any active dialog + while (mDialogControlLock == true) usleep(100000); + mDialogControlLock = true; + if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) { + if (currentDialog != NULL) { + mForceReject = true; + closeCurrentWindow(); + } + } + mInfoMessageDisplayed = true; + mDialogControlLock = false; + // Display info message dialog + InfoDlg inDlg( this ); + inDlg.updateLabel(to_display); + if (command[0] == 'K') inDlg.setKDEIcon(); + if (command[0] == 'I') inDlg.setInfoIcon(); + if (command[0] == 'W') inDlg.setWarningIcon(); + if (command[0] == 'E') inDlg.setErrorIcon(); + execDialog( &inDlg ); + mForceReject = false; + trinity_desktop_lock_closing_windows = false; + return; + } + if (command[0] == 'Q') { + to_display = command.data(); + to_display = to_display.remove(0,1); + // Lock out password dialogs and close any active dialog + while (mDialogControlLock == true) usleep(100000); + mDialogControlLock = true; + if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) { + if (currentDialog != NULL) { + mForceReject = true; + closeCurrentWindow(); + } + } + mInfoMessageDisplayed = true; + mDialogControlLock = false; + // Display query dialog + QueryDlg qryDlg( this ); + qryDlg.updateLabel(to_display); + qryDlg.setUnlockIcon(); + mForceReject = false; + execDialog( &qryDlg ); + if (mForceReject == false) { + pin_entry = qryDlg.getEntry(); + mInfoMessageDisplayed=false; + if (mPipeOpen_out == true) { + if (write(mPipe_fd_out, pin_entry, strlen(pin_entry)+1) == -1) { + // Error handler to shut up gcc warnings + } + if (write(mPipe_fd_out, "\n\r", 3) == -1) { + // Error handler to shut up gcc warnings + } + } + } + mForceReject = false; + trinity_desktop_lock_closing_windows = false; + return; + } +} + +//=========================================================================== +// +// Control pipe handler +// +ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() { + mParent = NULL; +} + +ControlPipeHandlerObject::~ControlPipeHandlerObject() { + // +} + +void ControlPipeHandlerObject::run(void) { + /* Create the FIFOs if they do not exist */ + umask(0); + mkdir(FIFO_DIR,0644); + mknod(FIFO_FILE, S_IFIFO|0644, 0); + chmod(FIFO_FILE, 0644); + + mParent->mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); + if (mParent->mPipe_fd > -1) { + mParent->mPipeOpen = true; + } + + mknod(FIFO_FILE_OUT, S_IFIFO|0600, 0); + chmod(FIFO_FILE_OUT, 0600); + + mParent->mPipe_fd_out = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK); + if (mParent->mPipe_fd_out > -1) { + mParent->mPipeOpen_out = true; + } + + int numread; + int retval; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(mParent->mPipe_fd, &rfds); + TQByteArray readbuf(128); + + while (mParent->mPipeOpen) { + TQString inputcommand = ""; + + // Wait for mParent->mPipe_fd to receive input + retval = select(mParent->mPipe_fd + 1, &rfds, NULL, NULL, NULL); + if (retval < 0) { + // ERROR + } + else if (retval) { + // New data is available + readbuf[0]=' '; + numread = read(mParent->mPipe_fd, readbuf.data(), 128); + readbuf[numread] = 0; + if (numread > 0) { + inputcommand += readbuf; + emit processCommand(inputcommand); + } + } + } +} + #include "lockprocess.moc" diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h index e1b8fcf52..3ef08c91b 100644 --- a/kdesktop/lock/lockprocess.h +++ b/kdesktop/lock/lockprocess.h @@ -22,12 +22,14 @@ #include <tqmessagebox.h> #include <tqpixmap.h> #include <tqdatetime.h> +#include <tqthread.h> #include <X11/Xlib.h> class KLibrary; class KWinModule; class KSMModalDialog; +class LockProcess; struct GreeterPluginHandle { KLibrary *library; @@ -43,6 +45,28 @@ typedef TQValueList<Window> TQXLibWindowList; //=========================================================================== // +// Control pipe handler +// +class ControlPipeHandlerObject : public TQObject +{ + Q_OBJECT + + public: + ControlPipeHandlerObject(); + ~ControlPipeHandlerObject(); + + public slots: + void run(); + + signals: + void processCommand(TQString); + + public: + LockProcess* mParent; +}; + +//=========================================================================== +// // Screen saver handling process. Handles screensaver window, // starting screensaver hacks, and password entry. // @@ -74,7 +98,6 @@ public slots: void quitSaver(); void preparePopup(); void cleanupPopup(); - void checkPipe(); void desktopResized(); void doDesktopResizeFinish(); void doFunctionKeyBroadcast(); @@ -101,6 +124,7 @@ private slots: void repaintRootWindowIfNeeded(); void startSecureDialog(); void slotMouseActivity(XEvent *event); + void processInputPipeCommand(TQString command); private: void configure(); @@ -121,7 +145,6 @@ private: bool startHack(); void stopHack(); void setupSignals(); - void setupPipe(); bool checkPass(); void stayOnTop(); void lockXF86(); @@ -215,6 +238,11 @@ private: int m_dialogPrevY; TQWidget* m_maskWidget; + + ControlPipeHandlerObject* mControlPipeHandler; + TQEventLoopThread* mControlPipeHandlerThread; + + friend class ControlPipeHandlerObject; }; #endif diff --git a/tdm/kfrontend/kgapp.cpp b/tdm/kfrontend/kgapp.cpp index 259e2666b..cc278f706 100644 --- a/tdm/kfrontend/kgapp.cpp +++ b/tdm/kfrontend/kgapp.cpp @@ -104,6 +104,11 @@ GreeterApp::GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap) : T init(); } +GreeterApp::~GreeterApp() +{ + // +} + void GreeterApp::init() { pingInterval = _isLocal ? 0 : _pingInterval; diff --git a/tdm/kfrontend/kgapp.h b/tdm/kfrontend/kgapp.h index 2c903634b..6150b4f5d 100644 --- a/tdm/kfrontend/kgapp.h +++ b/tdm/kfrontend/kgapp.h @@ -37,6 +37,7 @@ class GreeterApp : public TDEApplication { GreeterApp(); GreeterApp(Display *dpy); GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap); + ~GreeterApp(); virtual bool x11EventFilter( XEvent * ); protected: diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp index c603c54b7..2111a1e9d 100644 --- a/tdm/kfrontend/kgreeter.cpp +++ b/tdm/kfrontend/kgreeter.cpp @@ -221,7 +221,7 @@ KGreeter::~KGreeter() mControlPipeHandlerThread->terminate(); mControlPipeHandlerThread->wait(); delete mControlPipeHandler; - delete mControlPipeHandlerThread; +// delete mControlPipeHandlerThread; hide(); delete userList; diff --git a/tdm/kfrontend/sakdlg.cc b/tdm/kfrontend/sakdlg.cc index 4818c1cdd..e5ad75a88 100644 --- a/tdm/kfrontend/sakdlg.cc +++ b/tdm/kfrontend/sakdlg.cc @@ -165,7 +165,7 @@ SAKDlg::~SAKDlg() mControlPipeHandlerThread->terminate(); mControlPipeHandlerThread->wait(); delete mControlPipeHandler; - delete mControlPipeHandlerThread; +// delete mControlPipeHandlerThread; hide(); } |