Patch: That teletext page :)

Koos Vriezen koos.vriezen at xs4all.nl
Sun Oct 6 20:48:48 BST 2002


Hi,

I've been working on that crash from n-tv.de, which turned out to be that
'processEvent()' is quite evil (thanks Simon). I've attached a
patch which make LiveConnect calls real synchronous.
All LiveConnect sites(*) seems to be working except ... the
teletext site has some trouble loading. It does work, only there is some
blocking while loading (needs some further investigation).
Java <-> JS communication is also a lot faster now and, most importantly,
no crashes when closing a window that is in a blocking Java call.

Please review (also for the KProcess things),

Regards,

Koos

*)
http://www.n-tv.de/  -> teletext left side menu
http://members.ozemail.com.au/~dcrombie/java/Pendulum.htm
http://developer.netscape.com/docs/examples/java/hitman.html
-------------- next part --------------
Index: java/kjavaappletserver.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletserver.cpp,v
retrieving revision 1.53
diff -u -3 -p -r1.53 kjavaappletserver.cpp
--- java/kjavaappletserver.cpp	2002/09/22 13:18:58	1.53
+++ java/kjavaappletserver.cpp	2002/10/06 19:39:50
@@ -507,26 +507,20 @@ bool KJavaAppletServer::getMember(int co
 
     JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
 
-    process->send( KJAS_GET_MEMBER, args );
+    kdDebug(6100) << "KJavaAppletServer::getMember " << name << endl;
+    process->sendSync( KJAS_GET_MEMBER, args );
 
-    //dirty sync
-    extern QApplication *qApp;
-    int count = 100 + frame->size;
-    while (!frame->ready && --count > 0) {
-        usleep(50000); 
-        qApp->processEvents(100);
-    }
-
     bool retval = frame->ready;
     if (retval) {
         type = frame->args[0].toInt(&retval);
+        kdDebug(6100) << "KJavaAppletServer::getMember " << type << endl;
         if (retval && type >= 0) {
             rid = frame->args[1].toInt(&retval);
             value = frame->args[2];
         } else
             retval = false;
     } else {
-        kdError(6100) << "Error: timeout on Java  member return data" << endl;
+        kdError(6100) << "getMember: timeout" << endl;
         d->jsstack = frame->up; // FIXME: if(d->jsstack != frame)
     }
 
@@ -543,22 +537,17 @@ bool KJavaAppletServer::putMember(int co
     args.append( name );
     args.append( value );
 
+    kdDebug(6100) << "KJavaAppletServer::putMember " << name << endl;
     JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
-
-    process->send( KJAS_PUT_MEMBER, args );
 
-    extern QApplication *qApp;
-    int count = 100 + frame->size;
-    while (!frame->ready && --count > 0) {
-        usleep(50000); 
-        qApp->processEvents(100);
-    }
+    process->sendSync( KJAS_PUT_MEMBER, args );
 
     bool retval = frame->ready;
     if (retval) {
+        kdDebug(6100) << "KJavaAppletServer::putMember " << retval << endl;
         retval = frame->args[0].toInt(&retval);
     } else {
-        kdError(6100) << "Error: timeout on Java member return data" << endl;
+        kdError(6100) << "putMember: timeout" << endl;
         d->jsstack = frame->up;
     }
 
@@ -577,19 +566,14 @@ bool KJavaAppletServer::callMember(int c
         args.append(*it);
 
     JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
-
-    process->send( KJAS_CALL_MEMBER, args );
 
-    extern QApplication *qApp;
-    int count = 100 + frame->size;
-    while (!frame->ready && --count > 0) {
-        usleep(50000); 
-        qApp->processEvents(100);
-    }
+    kdDebug(6100) << "KJavaAppletServer::callMember " << name << endl;
+    process->sendSync( KJAS_CALL_MEMBER, args );
 
     bool retval = frame->ready;
     if (retval) {
         type = frame->args[0].toInt(&retval);
+        kdDebug(6100) << "KJavaAppletServer::callMember " << type << endl;
         if (retval && type > -1) {
             rid = frame->args[1].toInt(&retval);
             if (retval)
@@ -597,7 +581,7 @@ bool KJavaAppletServer::callMember(int c
         } else
             retval = false;
     } else {
-        kdError(6100) << "Error: timeout on Java  member return data" << endl;
+        kdError(6100) << "callMember: timeout return data" << endl;
         d->jsstack = frame->up;
     }
 
Index: java/kjavaprocess.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaprocess.h,v
retrieving revision 1.16
diff -u -3 -p -r1.16 kjavaprocess.h
--- java/kjavaprocess.h	2002/05/14 19:14:41	1.16
+++ java/kjavaprocess.h	2002/10/06 19:39:50
@@ -39,7 +39,7 @@
  */
 
 class KJavaProcessPrivate;
-class KJavaProcess : public QObject
+class KJavaProcess : public KProcess //QObject
 {
 Q_OBJECT
 
@@ -109,6 +109,7 @@ public:
      * out of the data, and then writes it standard out.
      */
     void send( char cmd_code, const QStringList& args );
+    void sendSync( char cmd_code, const QStringList& args );
 
     /**
      * Sends a command to the KJAS Applet Server by building a QByteArray
Index: java/kjavaprocess.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaprocess.cpp,v
retrieving revision 1.36
diff -u -3 -p -r1.36 kjavaprocess.cpp
--- java/kjavaprocess.cpp	2002/06/21 13:04:48	1.36
+++ java/kjavaprocess.cpp	2002/10/06 19:39:50
@@ -41,15 +41,17 @@ private:
     QPtrList<QByteArray> BufferList;
     QMap<QString, QString> systemProps;
     bool processKilled;
+    int sync_count;
 };
 
-KJavaProcess::KJavaProcess()
+KJavaProcess::KJavaProcess() : KProcess()
 {
     d = new KJavaProcessPrivate;
     d->BufferList.setAutoDelete( true );
     d->processKilled = false;
+    d->sync_count = 0;
     
-    javaProcess = new KProcess();
+    javaProcess = this; //new KProcess();
 
     connect( javaProcess, SIGNAL( wroteStdin( KProcess * ) ),
              this, SLOT( slotWroteData() ) );
@@ -70,7 +72,7 @@ KJavaProcess::~KJavaProcess()
         stopJava();
     }
 
-    delete javaProcess;
+    //delete javaProcess;
     delete d;
 }
 
@@ -175,7 +177,69 @@ void KJavaProcess::sendBuffer( QByteArra
         popBuffer();
     }
 }
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+void KJavaProcess::sendSync( char cmd_code, const QStringList& args ) {
+    kdDebug(6100) << ">KJavaProcess::sendSync " << d->sync_count << endl;
+    if (d->sync_count++ == 0)
+        javaProcess->suspend();
+    QByteArray* buff = addArgs( cmd_code, args );
+    storeSize( buff );
+    int dummy;
+    int size = buff->size();
+    char *data = buff->data();
+    fd_set fds;
+    timeval tv;
+    do {
+        FD_ZERO(&fds);
+        FD_SET(in[1], &fds);
+        tv.tv_sec = 5;
+        tv.tv_usec = 0;
+        int retval = select(in[1]+1, 0L, &fds, 0L, &tv);
+        FD_CLR(in[1], &fds);
+        if (retval < 0 && errno == EINTR) {
+            continue;
+        } else if (retval <= 0) {
+            kdError(6100) << "KJavaProcess::sendSync " << retval << endl;
+            goto bail_out;
+        } else if (KProcess::input_data) {
+            KProcess::slotSendData(dummy);
+        } else {
+            int nr = ::write(in[1], data, size);
+            size -= nr;
+            data += nr;
+        }
+    } while (size > 0);
 
+    do {
+        FD_ZERO(&fds);
+        FD_SET(out[0], &fds);
+        tv.tv_sec = 5;
+        tv.tv_usec = 0;
+        kdDebug(6100) << "KJavaProcess::sendSync bf read" << endl;
+        int retval = select(out[0]+1, &fds, 0L, 0L, &tv);
+        FD_CLR(out[0], &fds);
+        if (retval < 0) {
+            if (errno == EINTR)
+                continue;
+            kdError(6100) << "KJavaProcess::sendSync " << retval << endl;
+        } else if (retval == 0) {
+            kdError(6100) << "KJavaProcess::sendSync timeout" <<endl;
+        } else {
+            slotReceivedData(out[0], dummy);
+        }
+        break;
+    } while(true);
+bail_out:
+    delete buff;
+    if (--d->sync_count == 0)
+        javaProcess->resume();
+    kdDebug(6100) << "<KJavaProcess::sendSync " << d->sync_count << endl;
+}
+        
 void KJavaProcess::send( char cmd_code, const QStringList& args )
 {
     if( isRunning() )
Index: html/html_objectimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_objectimpl.cpp,v
retrieving revision 1.93
diff -u -3 -p -r1.93 html_objectimpl.cpp
--- html/html_objectimpl.cpp	2002/09/23 19:27:57	1.93
+++ html/html_objectimpl.cpp	2002/10/06 19:39:51
@@ -109,8 +109,10 @@ void LiveConnectElementImpl::liveConnect
     }
     script += ")";
 
-    timer->start(0, true);
     kdDebug(6036) << "HTMLEmbedElementImpl::liveConnectEvent " << script << endl;
+    KHTMLView* w = getDocument()->view();
+    w->part()->executeScript(this, script);
+    //timer->start(0, true);
 }
 
 void LiveConnectElementImpl::timerDone() {


More information about the kfm-devel mailing list