summaryrefslogtreecommitdiffstats
path: root/kdesktop
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-04-06 20:48:44 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-04-06 20:48:44 -0500
commitdc41de959b6b76263f8640c4075a6ed5b873b722 (patch)
tree1077a521b7adde84677d190f81f17e581dbb80ac /kdesktop
parent65ea5f153b83d2a30c667ac8b32708309c7ed173 (diff)
downloadtdebase-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
Diffstat (limited to 'kdesktop')
-rw-r--r--kdesktop/lock/lockprocess.cc314
-rw-r--r--kdesktop/lock/lockprocess.h32
2 files changed, 211 insertions, 135 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