Use threading and select instead of busywaiting on the lock control socket

This resolves the remainder of Bug 690
pull/2/head
Timothy Pearson 11 years ago
parent 65ea5f153b
commit dc41de959b

@ -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"

@ -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;
@ -41,6 +43,28 @@ struct GreeterPluginHandle {
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,
@ -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

@ -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;

@ -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:

@ -221,7 +221,7 @@ KGreeter::~KGreeter()
mControlPipeHandlerThread->terminate();
mControlPipeHandlerThread->wait();
delete mControlPipeHandler;
delete mControlPipeHandlerThread;
// delete mControlPipeHandlerThread;
hide();
delete userList;

@ -165,7 +165,7 @@ SAKDlg::~SAKDlg()
mControlPipeHandlerThread->terminate();
mControlPipeHandlerThread->wait();
delete mControlPipeHandler;
delete mControlPipeHandlerThread;
// delete mControlPipeHandlerThread;
hide();
}

Loading…
Cancel
Save