Crash: blocking JS and deleting a window
Koos Vriezen
koos.vriezen at xs4all.nl
Sat Oct 5 16:41:40 BST 2002
On Sat, 5 Oct 2002, Koos Vriezen wrote:
> On Sat, 5 Oct 2002, Koos Vriezen wrote:
>
> > On Sat, 5 Oct 2002, Simon Hausmann wrote:
> > >
> > > On a second though I don't understand how this can happen. The
> > > alert() triggers a messagebox with the window as parent, so it
> > > shouldn't be possible to close the window in the first place as the
> > > messagebox is modal. Any idea?
> >
> > Same for 'Open Location' dialog. Bug in Qt?
> >
> > There are other cases, eg calls to Java, that could block JS. Something
> > has to be done.
>
> Well, if this modal dialog can be solved elsewhere, we might not need a
> canDelete event if this ugly synchronization in KJavaAppletServer can be
> implemented differently:
> while (!frame->ready && --count > 0) {
> usleep(50000);
> qApp->processEvents(100);
> }
> Solution that I can think of is
> - Running kjs in a subprocess that can be killed
> - Return from evaluate with completion type UNFINISHED and continues
> running after data is arrived (or timed out)
> Both not very feasible (certainly for 3.1)
>
> Other suggestions?
Attached an attempt to stop blocking JS (line numbers maybe wrong). Where
should I put the 'stopLiveConnect()' call. Implemented like this, a crash
in KHTMLPart::clear occurs, when trying to close the
teletext window from http://www.n-tv.de. Some console traces:
kparts: Part::~Part 0x88038a0
kparts: deleting widget [KHTMLView pointer (0x8803b18) to widget kopf,
geometry=662x60+2000+2000] kopf
kjas: KJavaAppletServer::stopLiveConnect 0x87f45c0
kjas: KJavaAppletServer::stopLiveConnect framecount:1
One active JS blocking call
kjas: KJavaProcess::storeSize, size = 6
kjas: KJavaProcess::storeSize, size = 6
kjas continues with this call
......
kparts: KPart::slotWidgetDestroyed(), deleting part main
.....
kparts: Part::~Part 0x8786ad8
kparts: KPart::slotWidgetDestroyed(), deleting part <!--frame 1-->
kparts: Part::~Part 0x86d1ec0
kparts: KPart::slotWidgetDestroyed(), deleting part bottom
kparts: 0x873d288 emitting activePartChanged (nil)
khtml (jscript): Window::clear 0x86ba134
.......
kparts: Part::~Part 0x87f0ad0
kjas: KJavaAppletServer::slotJavaRequest: 2
kjas: KJavaAppletServer::slotJavaRequest: 0
kjas: KJavaAppletServer::slotJavaRequest:
kjas: ERROR: no context object for this id
kjas: KJavaAppletServer::stopLiveConnect after recount 0
No active blocking calls left
CRASH
Seems like implemented like this, its too late (doesn't help to put it in
KHTMLPart::~KHTMLPart before clear().
>
> Koos
>
>
-------------- next part --------------
Index: khtml_part.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtml_part.cpp,v
retrieving revision 1.751
diff -u -3 -p -r1.751 khtml_part.cpp
--- khtml_part.cpp 2002/09/29 09:25:33 1.751
+++ khtml_part.cpp 2002/10/05 14:42:18
@@ -854,6 +859,12 @@ void KHTMLPart::clear()
if ( d->m_bCleared )
return;
d->m_bCleared = true;
+
+#ifndef Q_WS_QWS
+ // make sure we don't have any JS doing blocking Java calls
+ if( d->m_javaContext )
+ d->m_javaContext->stopLiveConnect();
+#endif
d->m_bClearing = true;
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/05 14:42:18
@@ -63,14 +63,19 @@
#define KJAS_AUDIOCLIP_PLAY (char)20
#define KJAS_AUDIOCLIP_LOOP (char)21
#define KJAS_AUDIOCLIP_STOP (char)22
class JSStackNode {
public:
- JSStackNode(JSStackNode *u) : ready(false), size(u ? u->size+1: 1), up(u) {}
+ JSStackNode(JSStackNode *u, int cid)
+ : ready(false), stop(false),
+ size(u ? u->size+1: 1), contextid(cid), up(u) {}
bool ready;
+ bool stop;
QStringList args;
int size;
+ int contextid;
JSStackNode *up;
};
@@ -437,6 +442,10 @@ void KJavaAppletServer::slotJavaRequest(
cmd = QString::fromLatin1( "resizeapplet" );
break;
case KJAS_GET_URLDATA:
//here we need to get some data for a class loader and send it back...
kdDebug(6100) << "GetURLData from classloader: "<< contextID
@@ -505,7 +514,7 @@ bool KJavaAppletServer::getMember(int co
args.append( QString::number(objid) );
args.append( name );
- JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
+ JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack, contextId);
process->send( KJAS_GET_MEMBER, args );
@@ -515,6 +524,7 @@ bool KJavaAppletServer::getMember(int co
while (!frame->ready && --count > 0) {
usleep(50000);
qApp->processEvents(100);
+ if (frame->stop) return false;
}
bool retval = frame->ready;
@@ -543,7 +553,7 @@ bool KJavaAppletServer::putMember(int co
args.append( name );
args.append( value );
- JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
+ JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack, contextId);
process->send( KJAS_PUT_MEMBER, args );
@@ -552,6 +562,7 @@ bool KJavaAppletServer::putMember(int co
while (!frame->ready && --count > 0) {
usleep(50000);
qApp->processEvents(100);
+ if (frame->stop) return false;
}
bool retval = frame->ready;
@@ -576,7 +587,7 @@ bool KJavaAppletServer::callMember(int c
for (QStringList::const_iterator it = fargs.begin(); it != fargs.end(); it++)
args.append(*it);
- JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack);
+ JSStackNode * frame = d->jsstack = new JSStackNode(d->jsstack, contextId);
process->send( KJAS_CALL_MEMBER, args );
@@ -585,6 +596,7 @@ bool KJavaAppletServer::callMember(int c
while (!frame->ready && --count > 0) {
usleep(50000);
qApp->processEvents(100);
+ if (frame->stop) return false;
}
bool retval = frame->ready;
@@ -614,4 +626,26 @@ void KJavaAppletServer::derefObject(int
process->send( KJAS_DEREF_OBJECT, args );
}
+
+void KJavaAppletServer::stopLiveConnect(int contextId) {
+ int framecount = 0;
+ JSStackNode * frame = d->jsstack;
+ while (frame) {
+ if (frame->contextid == contextId) {
+ frame->stop = true;
+ framecount++;
+ }
+ frame = frame->up;
+ }
+ while (framecount) {
+ qApp->processEvents(100);
+ framecount = 0;
+ frame = d->jsstack;
+ while (frame) {
+ if (frame->contextid == contextId)
+ framecount++;
+ frame = frame->up;
+ }
+ }
+}
+
#include "kjavaappletserver.moc"
Index: java/kjavaappletcontext.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletcontext.cpp,v
retrieving revision 1.30
diff -u -3 -p -r1.30 kjavaappletcontext.cpp
--- java/kjavaappletcontext.cpp 2002/07/06 02:38:47 1.30
+++ java/kjavaappletcontext.cpp 2002/10/05 14:42:19
@@ -51,6 +51,8 @@ KJavaAppletContext::KJavaAppletContext()
id = contextCount;
server->createContext( id, this );
+ candoliveconnect = true;
+
contextCount++;
}
@@ -163,6 +165,22 @@ void KJavaAppletContext::received( const
tmp->resizeAppletWidget( width, height );
}
}
else if (cmd.startsWith(QString::fromLatin1("audioclip_"))) {
kdDebug(6002) << "process Audio command (not yet implemented): " << cmd << " " << arg[0] << endl;
}
@@ -193,14 +211,20 @@ void KJavaAppletContext::received( const
}
bool KJavaAppletContext::getMember(KJavaApplet * applet, const unsigned long objid, const QString & name, int & type, unsigned long & rid, QString & value) {
+ if (!candoliveconnect)
+ return false;
return server->getMember(id, applet->appletId(), objid, name, type, rid, value);
}
bool KJavaAppletContext::putMember(KJavaApplet * applet, const unsigned long objid, const QString & name, const QString & value) {
+ if (!candoliveconnect)
+ return false;
return server->putMember(id, applet->appletId(), objid, name, value);
}
bool KJavaAppletContext::callMember(KJavaApplet * applet, const unsigned long objid, const QString & name, const QStringList & args, int & type, unsigned long & retobjid, QString & value) {
+ if (!candoliveconnect)
+ return false;
return server->callMember(id, applet->appletId(), objid, name, args, type, retobjid, value);
}
@@ -208,4 +232,8 @@ void KJavaAppletContext::derefObject(KJa
server->derefObject(id, applet->appletId(), jid);
}
+void KJavaAppletContext::stopLiveConnect() {
+ candoliveconnect = false;
+ server->stopLiveConnect(id);
+}
#include <kjavaappletcontext.moc>
Index: java/kjavaappletcontext.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletcontext.h,v
retrieving revision 1.17
diff -u -3 -p -r1.17 kjavaappletcontext.h
--- java/kjavaappletcontext.h 2002/05/25 11:50:27 1.17
+++ java/kjavaappletcontext.h 2002/10/05 14:42:19
@@ -100,6 +100,7 @@ public:
bool callMember(KJavaApplet *, const unsigned long, const QString &, const QStringList &, int &, unsigned long &, QString &);
void derefObject(KJavaApplet *, const unsigned long id);
+ void stopLiveConnect();
signals:
/**
* Signals the KHMTL Part to show this as the status message.
@@ -124,6 +125,7 @@ protected slots:
private:
int id;
KJavaAppletContextPrivate* d;
+ bool candoliveconnect;
};
Index: java/kjavaappletserver.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletserver.h,v
retrieving revision 1.21
diff -u -3 -p -r1.21 kjavaappletserver.h
--- java/kjavaappletserver.h 2002/05/25 11:50:27 1.21
+++ java/kjavaappletserver.h 2002/10/05 14:42:19
@@ -131,6 +131,7 @@ public:
bool putMember(int contextId, int appletId, const unsigned long, const QString &, const QString &);
bool callMember(int contextId, int appletId, const unsigned long, const QString &, const QStringList &, int &, unsigned long &, QString &);
void derefObject(int contextId, int appletId, const unsigned long id);
+ void stopLiveConnect(int contextId);
protected:
void setupJava( KJavaProcess* p );
More information about the kfm-devel
mailing list