[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: PATCH: make kdeinit exit when it's not needed anymore
From: David Faure <david () mandrakesoft ! com>
Date: 2000-11-29 22:57:18
[Download RAW message or body]
The attached patches make kdeinit exit 10 seconds after the last
KDE application (DCOP-enabled) exits.
This fixes problems that people are having when using KDE applications
out of KDE (3 or 4 processes are left running after they close the last
KDE application).
In short, dcopserver has a reference counter of registered applications,
which excludes the daemons (klauncher, kded and knotify).
In more details (i.e. for Waldo :), when dcopserver's refcount is 0,
a timer is started, and if it's still the case after 10 seconds
[this is to prevent KDE from exiting on startup :)], then it emits a DCOP
signal "terminateKDE()". I had to add support for dcop signals _sent_
by the DCOPServer.
KLauncher is connected to this signal, and upon receiving it,
it sends a command to kdeinit to tell it to exit. I have tested, and this
effectively kills the daemons as well, as expected.
This is a bit central to KDE, so a bit of peer review can't hurt :-)
--=20
David FAURE, david@mandrakesoft.com, faure@kde.org
http://www.mandrakesoft.com/~david/, http://www.konqueror.org/
KDE, Making The Future of Computing Available Today
See http://www.kde.org/kde1-and-kde2.html for how to set up KDE 2
["dcop.diff" (text/x-c)]
Index: dcopserver.cpp
===================================================================
RCS file: /home/kde/kdelibs/dcop/dcopserver.cpp,v
retrieving revision 1.108
diff -u -p -r1.108 dcopserver.cpp
--- dcopserver.cpp 2000/11/23 00:43:48 1.108
+++ dcopserver.cpp 2000/11/29 22:19:23
@@ -1,5 +1,7 @@
/*****************************************************************
+#include "dcopserver.h"
+
Copyright (c) 1999,2000 Preston Brown <pbrown@kde.org>
Copyright (c) 1999,2000 Matthias Ettrich <ettrich@kde.org>
@@ -45,6 +47,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
#include <qtextstream.h>
#include <qdatastream.h>
#include <qstack.h>
+#include <qtimer.h>
#include <dcopserver.h>
#include <dcopsignals.h>
@@ -661,7 +664,7 @@ extern "C" int _IceTransNoListen(const c
#endif
DCOPServer::DCOPServer(bool _only_local)
- : QObject(0,0), appIds(263), clients(263)
+ : QObject(0,0), appIds(263), clients(263), currentClientNumber(0)
{
serverKey = 42;
@@ -743,6 +746,9 @@ DCOPServer::DCOPServer(bool _only_local)
char c = 0;
write(ready[1], &c, 1); // dcopserver is started
close(ready[1]);
+
+ m_timer = new QTimer(this);
+ connect( m_timer, SIGNAL(timeout()), this, SLOT(slotTerminate()) );
}
DCOPServer::~DCOPServer()
@@ -866,6 +872,13 @@ void DCOPServer::removeConnection( void*
#ifndef NDEBUG
qDebug("DCOP: unregister '%s'", conn->appId.data() );
#endif
+ if ( conn->appId.left(9) != "klauncher" && conn->appId != "kded" && \
conn->appId != "knotify" ) + {
+ currentClientNumber--;
+#ifndef NDEBUG
+ qDebug("DCOP: number of clients is now down to %d", currentClientNumber \
); +#endif
+ }
appIds.remove( conn->appId );
QPtrDictIterator<DCOPConnection> it( clients );
@@ -892,8 +905,20 @@ void DCOPServer::removeConnection( void*
}
delete conn;
+
+ if ( currentClientNumber == 0 )
+ {
+ m_timer->start( 10000 ); // if within 10 seconds nothing happens, we'll \
terminate + }
}
+void DCOPServer::slotTerminate()
+{
+ fprintf( stderr, "DCOPServer : slotTerminate() -> sending terminateKDE \
signal.\n" ); + QByteArray data;
+ dcopSignals->emitSignal(0L /* dcopserver */, "terminateKDE()", data, false);
+}
+
bool DCOPServer::receive(const QCString &/*app*/, const QCString &obj,
const QCString &fun, const QByteArray& data,
QCString& replyType, QByteArray &replyData,
@@ -922,9 +947,22 @@ bool DCOPServer::receive(const QCString
appIds.remove( conn->appId );
}
-#ifndef NDEBUG
if ( conn->appId.isNull() )
- qDebug("DCOP: register '%s'", app2.data() );
+ {
+ if ( app2.left(9) != "klauncher" && app2 != "kded" && app2 != \
"knotify" ) + {
+ currentClientNumber++;
+ m_timer->stop(); // abort termination if we were planning \
one +#ifndef NDEBUG
+ qDebug("DCOP: register '%s' -> number of clients is now %d", \
app2.data(), currentClientNumber ); +#endif
+ }
+#ifndef NDEBUG
+ else
+ qDebug("DCOP: register '%s'", app2.data() );
+#endif
+ }
+#ifndef NDEBUG
else
qDebug("DCOP: '%s' now known as '%s'", conn->appId.data(), app2.data() );
#endif
Index: dcopserver.h
===================================================================
RCS file: /home/kde/kdelibs/dcop/dcopserver.h,v
retrieving revision 1.20
diff -u -p -r1.20 dcopserver.h
--- dcopserver.h 2000/09/05 22:05:00 1.20
+++ dcopserver.h 2000/11/29 22:19:24
@@ -46,6 +46,7 @@ class DCOPConnection;
class DCOPListener;
class DCOPSignalConnectionList;
class DCOPSignals;
+class QTimer;
typedef QValueList<QCString> QCStringList;
@@ -85,9 +86,9 @@ public:
void processMessage( IceConn iceConn, int opcode, unsigned long length, Bool \
swap); void ioError( IceConn iceConn );
- virtual bool receive(const QCString &app, const QCString &obj,
- const QCString &fun, const QByteArray& data,
- QCString& replyType, QByteArray &replyData, IceConn iceConn);
+ bool receive(const QCString &app, const QCString &obj,
+ const QCString &fun, const QByteArray& data,
+ QCString& replyType, QByteArray &replyData, IceConn iceConn);
DCOPConnection *findApp(const QCString &appId);
@@ -98,6 +99,7 @@ public:
private slots:
void newClient( int socket );
void processData( int socket );
+ void slotTerminate();
private:
int majorOpcode;
@@ -106,6 +108,8 @@ private:
QAsciiDict<DCOPConnection> appIds;
QPtrDict<DCOPConnection> clients;
DCOPSignals *dcopSignals;
+ int currentClientNumber;
+ QTimer * m_timer;
};
extern DCOPServer* the_server;
Index: dcopsignals.cpp
===================================================================
RCS file: /home/kde/kdelibs/dcop/dcopsignals.cpp,v
retrieving revision 1.4
diff -u -p -r1.4 dcopsignals.cpp
--- dcopsignals.cpp 2000/08/03 20:45:14 1.4
+++ dcopsignals.cpp 2000/11/29 22:19:25
@@ -56,7 +56,7 @@ DCOPSignals::emitSignal( DCOPConnection
}
else if (!current->sender.isEmpty())
{
- if (current->sender == conn->appId)
+ if ((conn && current->sender == conn->appId) || (current->sender == \
"DCOPServer")) doSend = true;
}
else
@@ -74,7 +74,7 @@ DCOPSignals::emitSignal( DCOPConnection
doSend = false;
if (doSend)
{
- the_server->sendMessage(current->recvConn, conn->appId,
+ the_server->sendMessage(current->recvConn, conn ? conn->appId : \
QCString("DCOPServer"),
current->recvConn->appId, current->recvObj,
current->slot, data);
}
Index: dcopsignals.h
===================================================================
RCS file: /home/kde/kdelibs/dcop/dcopsignals.h,v
retrieving revision 1.2
diff -u -p -b -r1.2 dcopsignals.h
--- dcopsignals.h 2000/08/03 20:45:14 1.2
+++ dcopsignals.h 2000/11/29 22:39:14
@@ -61,6 +61,7 @@ public:
/**
* Client "conn" emits the signal "fun" with "data" as arguments.
+ * conn is 0L if the dcopserver sends the signal itself
*
* The emitting object is encoded in "fun".
*
["klauncher.diff" (text/plain)]
? klauncher.diff
? klauncher.cpp.fix.for.quotes
Index: klauncher.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/klauncher/klauncher.cpp,v
retrieving revision 1.39
diff -u -p -b -r1.39 klauncher.cpp
--- klauncher.cpp 2000/11/06 10:12:13 1.39
+++ klauncher.cpp 2000/11/29 22:50:32
@@ -132,6 +132,8 @@ KLauncher::KLauncher(int _kdeinitSocket)
dcopClient()->setNotifications( true );
connect(dcopClient(), SIGNAL( applicationRegistered( const QCString &)),
this, SLOT( slotAppRegistered( const QCString &)));
+ dcopClient()->connectDCOPSignal( "DCOPServer", "", "terminateKDE()",
+ objId(), "terminateKDE()", false );
QString prefix = locateLocal("socket", "klauncher");
KTempFile domainname(prefix, QString::fromLatin1(".slave-socket"));
@@ -267,7 +269,17 @@ KLauncher::process(const QCString &fun,
IdleSlave *slave;
for(slave = mSlaveList.first(); slave; slave = mSlaveList.next())
slave->reparseConfiguration();
+ replyType = "void";
return true;
+ }
+ else if (fun == "terminateKDE()")
+ {
+ kdDebug() << "KLauncher::process ---> terminateKDE" << endl;
+ klauncher_header request_header;
+ request_header.cmd = LAUNCHER_TERMINATE_KDE;
+ request_header.arg_length = 0;
+ write(kdeinitSocket, &request_header, sizeof(request_header));
+ destruct(0);
}
if (KUniqueApplication::process(fun, data, replyType, replyData))
{
Index: klauncher_cmds.h
===================================================================
RCS file: /home/kde/kdelibs/kio/klauncher/klauncher_cmds.h,v
retrieving revision 1.3
diff -u -p -b -r1.3 klauncher_cmds.h
--- klauncher_cmds.h 2000/02/11 15:28:50 1.3
+++ klauncher_cmds.h 2000/11/29 22:50:32
@@ -90,5 +90,7 @@ typedef struct
* char *envs: environment strings.
* char *tty: tty to redirect stdout/stderr to.
*/
+
+#define LAUNCHER_TERMINATE_KDE 7
#endif
["kinit.cpp.diff" (text/x-c)]
Index: kinit.cpp
===================================================================
RCS file: /home/kde/kdelibs/kinit/kinit.cpp,v
retrieving revision 1.49
diff -u -p -r1.49 kinit.cpp
--- kinit.cpp 2000/11/26 23:04:17 1.49
+++ kinit.cpp 2000/11/29 22:50:45
@@ -82,8 +82,12 @@ struct {
int (*launcher_func)(int);
} d;
+extern "C" {
+int kdeinit_xio_errhandler( Display * );
+}
+
/*
- * Close fd's which are only usefull for the parent process.
+ * Close fd's which are only useful for the parent process.
* Restore default signal handlers.
*/
static void close_fds()
@@ -192,12 +196,17 @@ static pid_t launch(int argc, const char
d.handle = 0;
if (lib.right(3) == ".la")
+ {
d.handle = lt_dlopen( lib.data() );
+ if (!d.handle )
+ {
+ const char * ltdlError = lt_dlerror();
+ if ( ltdlError && strcmp(ltdlError,"file not found") )
+ fprintf(stderr, "Could not dlopen library %s: %s\n", lib.data(), \
ltdlError != 0 ? ltdlError : "(null)" ); + }
+ }
if (!d.handle )
{
- const char * ltdlError = lt_dlerror();
- if ( ltdlError && strcmp(ltdlError,"file not found") )
- fprintf(stderr, "Could not dlopen library %s: %s\n", lib.data(), ltdlError \
!= 0 ? ltdlError : "(null)" ); d.result = 2; // Try execing
write(d.fd[1], &d.result, 1);
@@ -549,7 +558,7 @@ static void handle_launcher_request(int
}
klauncher_header request_header;
- char *request_data;
+ char *request_data = 0L;
int result = read_socket(sock, (char *) &request_header, sizeof(request_header));
if (result != 0)
{
@@ -557,16 +566,19 @@ static void handle_launcher_request(int
kill_launcher();
return;
}
-
- request_data = (char *) malloc(request_header.arg_length);
- result = read_socket(sock, request_data, request_header.arg_length);
- if (result != 0)
+ if ( request_header.arg_length != 0 )
{
- if (launcher)
- kill_launcher();
- free(request_data);
- return;
+ request_data = (char *) malloc(request_header.arg_length);
+
+ result = read_socket(sock, request_data, request_header.arg_length);
+ if (result != 0)
+ {
+ if (launcher)
+ kill_launcher();
+ free(request_data);
+ return;
+ }
}
if (request_header.cmd == LAUNCHER_EXEC)
@@ -647,8 +659,14 @@ static void handle_launcher_request(int
return;
}
setenv( env_name, env_value, 1);
+ }
+ else if (request_header.cmd == LAUNCHER_TERMINATE_KDE)
+ {
+ fprintf(stderr,"kdeinit::LAUNCHER_TERMINATE_KDE -> terminateKDE\n");
+ kdeinit_xio_errhandler( 0L );
}
- free(request_data);
+ if (request_data)
+ free(request_data);
}
static void handle_requests(pid_t waitForPid)
@@ -796,6 +814,7 @@ static void kdeinit_library_path()
strcpy(sock_file, socketName.data());
}
+/*
static void output_kmapnotify_path()
{
KInstance instance( "kdeinit" );
@@ -813,11 +832,8 @@ static void output_kmapnotify_path()
}
printf("%s\n", (const char *)output);
-}
-
-extern "C" {
-int kdeinit_xio_errhandler( Display * );
}
+*/
int kdeinit_xio_errhandler( Display * )
{
@@ -872,7 +888,7 @@ int main(int argc, char **argv, char **e
int launch_klauncher = 1;
int launch_kded = 1;
int keep_running = 1;
- int libkmapnotify = 0;
+ //int libkmapnotify = 0;
/** Save arguments first... **/
char **safe_argv = (char **) malloc( sizeof(char *) * argc);
@@ -887,15 +903,15 @@ int main(int argc, char **argv, char **e
launch_kded = 0;
if (strcmp(safe_argv[i], "--exit") == 0)
keep_running = 0;
- if (strcmp(safe_argv[i], "--libkmapnotify") == 0)
- libkmapnotify = 1;
+ //if (strcmp(safe_argv[i], "--libkmapnotify") == 0)
+ // libkmapnotify = 1;
}
/** Output path to stdout if libkmapnotify was specified **/
- if (libkmapnotify) {
+ /*if (libkmapnotify) {
output_kmapnotify_path();
return 0;
- }
+ }*/
/** Make process group leader (for shutting down children later) **/
if(keep_running)
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic