[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: patch for much more stable nsplugins
From: Stefan Schimanski <sts () caldera ! de>
Date: 2001-01-25 18:02:48
[Download RAW message or body]
Hi,
here is a patch for nsplugins which fixes a lot of things:
* avoid deadlocks of konqi and nspluginviewer with concurrent synchronous
dcop calls
* updated kxt.cpp/h to match the current qt-copy qxt.cpp/h
* updated socket notifier handling in viewer/viewer to match that from qt-copy
* display some status information while loading in konqi's status bar
* destroy streams correctly on shutdown of a plugin (seems to fix a great
number of bug reports)
* removed some debug output
I've tested this for around 15 minutes with different web sites, especially
with Flash 4 and Plugger. I wasn't able to get any crash anymore. Even
www.newgrounds.com seems to work fine now. Please check it out. If nobody
objects until tomorrow I will commit it.
Schimmi
["nsplugins.patch" (text/x-c++)]
Index: NSPluginCallbackIface.h
===================================================================
RCS file: /home/kde/kdebase/nsplugins/NSPluginCallbackIface.h,v
retrieving revision 1.5
diff -u -p -B -w -r1.5 NSPluginCallbackIface.h
--- NSPluginCallbackIface.h 2001/01/07 15:56:59 1.5
+++ NSPluginCallbackIface.h 2001/01/25 17:43:33
@@ -34,8 +34,8 @@ class NSPluginCallbackIface : virtual pu
k_dcop:
- virtual void requestURL(QString url, QString target) = 0;
- virtual void statusMessage( QString msg ) = 0;
+ virtual ASYNC requestURL(QString url, QString target) = 0;
+ virtual ASYNC statusMessage( QString msg ) = 0;
};
Index: nspluginloader.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/nspluginloader.cpp,v
retrieving revision 1.21
diff -u -p -B -w -r1.21 nspluginloader.cpp
--- nspluginloader.cpp 2001/01/07 16:19:24 1.21
+++ nspluginloader.cpp 2001/01/25 17:43:34
@@ -322,7 +322,8 @@ void NSPluginLoader::processTerminated(K
NSPluginInstance *NSPluginLoader::newInstance(QWidget *parent, QString url,
QString mimeType, bool embed,
- QStringList argn, QStringList argv)
+ QStringList argn, QStringList argv,
+ QString appId, QString callbackId )
{
kdDebug() << "-> NSPluginLoader::NewInstance( parent=" << (void*)parent << ", \
url=" << url << ", mime=" << mimeType << ", ...)" << endl;
@@ -385,7 +386,7 @@ NSPluginInstance *NSPluginLoader::newIns
// get plugin instance
- DCOPRef inst_ref = cls->newInstance( url, mime, embed, argn, argv );
+ DCOPRef inst_ref = cls->newInstance( url, mime, embed, argn, argv, appId, \
callbackId ); if ( inst_ref.isNull() )
{
kdDebug() << "Couldn't create plugin instance" << endl;
Index: nspluginloader.h
===================================================================
RCS file: /home/kde/kdebase/nsplugins/nspluginloader.h,v
retrieving revision 1.10
diff -u -p -B -w -r1.10 nspluginloader.h
--- nspluginloader.h 2001/01/07 16:19:24 1.10
+++ nspluginloader.h 2001/01/25 17:43:34
@@ -65,7 +65,8 @@ public:
NSPluginInstance *newInstance(QWidget *parent,
QString url, QString mimeType, bool embed,
- QStringList argn, QStringList argv);
+ QStringList argn, QStringList argv,
+ QString appId, QString callbackId );
static NSPluginLoader *instance();
void release();
Index: plugin_part.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/plugin_part.cpp,v
retrieving revision 1.33
diff -u -p -B -w -r1.33 plugin_part.cpp
--- plugin_part.cpp 2001/01/07 16:19:24 1.33
+++ plugin_part.cpp 2001/01/25 17:43:34
@@ -200,9 +200,9 @@ bool PluginPart::openURL(const KURL &url
emit setStatusBarText( i18n("Loading Netscape plugin for \
%1").arg(url.prettyURL()) );
// create plugin widget
- NSPluginInstance *inst = _loader->newInstance( _canvas, surl, smime, embed, \
argn, argv ); + NSPluginInstance *inst = _loader->newInstance( _canvas, surl, \
smime, embed, argn, argv, + \
kapp->dcopClient()->appId(), _callback->objId() ); if ( inst ) {
- inst->setCallback(kapp->dcopClient()->appId(), _callback->objId());
inst->resize( _canvas->width(), _canvas->height() );
inst->show();
_widget = inst;
Index: plugin_part.h
===================================================================
RCS file: /home/kde/kdebase/nsplugins/plugin_part.h,v
retrieving revision 1.16
diff -u -p -B -w -r1.16 plugin_part.h
--- plugin_part.h 2001/01/07 15:56:59 1.16
+++ plugin_part.h 2001/01/25 17:43:34
@@ -22,16 +22,13 @@ class PluginPart;
class NSPluginCallback : public NSPluginCallbackIface
{
public:
-
NSPluginCallback(PluginPart *part);
- virtual void requestURL(QString url, QString target);
- virtual void statusMessage( QString msg );
+ ASYNC requestURL(QString url, QString target);
+ ASYNC statusMessage( QString msg );
private:
-
PluginPart *_part;
-
};
Index: pluginscan.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/pluginscan.cpp,v
retrieving revision 1.27
diff -u -p -B -w -r1.27 pluginscan.cpp
--- pluginscan.cpp 2001/01/16 23:03:29 1.27
+++ pluginscan.cpp 2001/01/25 17:43:34
@@ -359,7 +359,6 @@ void writeServicesFile( QStringList mime
void removeExistingExtensions( QString &extension )
{
- kdDebug() << "========> extension = " << extension << endl;
QStringList filtered;
QStringList exts = QStringList::split( ",", extension );
for ( QStringList::Iterator it=exts.begin(); it!=exts.end(); ++it ) {
@@ -367,8 +366,6 @@ void removeExistingExtensions( QString &
KMimeType::Ptr mime = KMimeType::findByURL( KURL("file:///foo."+ext ),
0, true, true );
- kdDebug() << "mime=" << mime->name() << " " << endl;
- kdDebug() << "kde=" << mime->property( "X-KDE-nsplugin" ).toString() << \
endl; if( mime->name()=="application/octet-stream" ||
mime->comment().left(8)=="Netscape" ) {
kdDebug() << "accepted" << endl;
Index: viewer/NSPluginClassIface.h
===================================================================
RCS file: /home/kde/kdebase/nsplugins/viewer/NSPluginClassIface.h,v
retrieving revision 1.12
diff -u -p -B -w -r1.12 NSPluginClassIface.h
--- viewer/NSPluginClassIface.h 2000/09/17 20:39:23 1.12
+++ viewer/NSPluginClassIface.h 2001/01/25 17:43:34
@@ -48,7 +48,8 @@ class NSPluginClassIface : virtual publi
k_dcop:
virtual DCOPRef newInstance(QString url, QString mimeType, bool embed,
- QStringList argn, QStringList argv) = 0;
+ QStringList argn, QStringList argv,
+ QString appId, QString callbackId ) = 0;
virtual QString getMIMEDescription() = 0;
};
@@ -67,8 +68,6 @@ k_dcop:
virtual int setWindow(int remove=0) = 0;
virtual void resizePlugin(int w, int h) = 0;
-
- virtual void setCallback(QCString _app, QCString _obj) = 0;
};
Index: viewer/kxt.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/viewer/kxt.cpp,v
retrieving revision 1.9
diff -u -p -B -w -r1.9 kxt.cpp
--- viewer/kxt.cpp 2000/08/31 12:50:22 1.9
+++ viewer/kxt.cpp 2001/01/25 17:43:34
@@ -2,7 +2,7 @@
kxt.cpp - Xt enabled Qt classed (derived from Qt Extension QXt)
- Copyright (c) 2000 Stefan Schimanski <1Stein@gmx.de>
+ Copyright (c) 2000,2001 Stefan Schimanski <1Stein@gmx.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -282,6 +282,7 @@ static void np_do_timers( void*, void* )
int interval = QMIN(tm->tv_sec,INT_MAX/1000)*1000 + tm->tv_usec/1000;
np_set_timer( interval );
}
+ qxtapp->sendPostedEvents();
}
/*!
@@ -620,4 +621,4 @@ void KXtWidget::resizeEvent( QResizeEven
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
XtResizeWidget( xtw, width(), height(), preferred.border_width );
}
-#include "kxt.moc"
+
Index: viewer/nsplugin.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/viewer/nsplugin.cpp,v
retrieving revision 1.50
diff -u -p -B -w -r1.50 nsplugin.cpp
--- viewer/nsplugin.cpp 2001/01/24 19:47:44 1.50
+++ viewer/nsplugin.cpp 2001/01/25 17:43:35
@@ -283,19 +283,20 @@ NPError g_NPN_SetValue(NPP /*instance*/,
NSPluginInstance::NSPluginInstance(NPP privateData, NPPluginFuncs *pluginFuncs,
KLibrary *handle, int width, int height,
QString src, QString /*mime*/,
+ QString appId, QString callbackId,
QObject *parent, const char* name )
: QObject( parent, name ), DCOPObject()
{
_npp = privateData;
_npp->ndata = this;
_destroyed = false;
- _callback = 0;
_handle = handle;
_width = width;
_height = height;
_tempFiles.setAutoDelete( true );
_streams.setAutoDelete( true );
_waitingRequests.setAutoDelete( true );
+ _callback = new NSPluginCallbackIface_stub( appId.latin1(), callbackId.latin1() \
);
KURL base(src);
base.setFileName( QString::null );
@@ -351,6 +352,13 @@ void NSPluginInstance::destroy()
kdDebug(1431) << "delete streams" << endl;
_waitingRequests.clear();
+
+ for( NSPluginStreamBase *s=_streams.first(); s!=0; ) {
+ NSPluginStreamBase *next = _streams.next();
+ s->stop();
+ s = next;
+ }
+
_streams.clear();
kdDebug(1431) << "delete callbacks" << endl;
@@ -464,10 +472,8 @@ void NSPluginInstance::requestURL( const
void NSPluginInstance::emitStatus(const QString &message)
{
- kdDebug(1431) << "-> NSPluginInstance::emitStatus " << message << endl;
if( _callback )
_callback->statusMessage( message );
- kdDebug(1431) << "<- NSPluginInstance::emitStatus " << endl;
}
@@ -642,13 +648,6 @@ void NSPluginInstance::addTempFile(KTemp
_tempFiles.append(tmpFile);
}
-
-void NSPluginInstance::setCallback(QCString app, QCString obj)
-{
- delete _callback;
- _callback = new NSPluginCallbackIface_stub(app, obj);
-}
-
/***************************************************************************/
NSPluginViewer::NSPluginViewer( QCString dcopId,
@@ -825,7 +824,8 @@ void NSPluginClass::shutdown()
DCOPRef NSPluginClass::newInstance(QString url, QString mimeType, bool embed,
- QStringList argn, QStringList argv)
+ QStringList argn, QStringList argv,
+ QString appId, QString callbackId )
{
kdDebug(1431) << "-> NSPluginClass::NewInstance" << endl;
@@ -863,7 +863,8 @@ DCOPRef NSPluginClass::newInstance(QStri
// Create plugin instance object
NSPluginInstance *inst = new NSPluginInstance( npp, &_pluginFuncs, _handle,
- width, height, baseURL, mimeType, \
this ); + width, height, baseURL, \
mimeType, + appId, callbackId, this \
);
// create plugin instance
NPError error = _pluginFuncs.newp(mime, npp, embed ? NP_EMBED : NP_FULL,
@@ -924,6 +925,10 @@ NSPluginStreamBase::~NSPluginStreamBase(
}
+void NSPluginStreamBase::stop()
+{
+ finish( true );
+}
bool NSPluginStreamBase::create( QString url, QString mimeType, void *notify )
Index: viewer/nsplugin.h
===================================================================
RCS file: /home/kde/kdebase/nsplugins/viewer/nsplugin.h,v
retrieving revision 1.24
diff -u -p -B -w -r1.24 nsplugin.h
--- viewer/nsplugin.h 2001/01/07 15:56:59 1.24
+++ viewer/nsplugin.h 2001/01/25 17:43:35
@@ -69,6 +69,7 @@ public:
KURL url() { return _url; };
int pos() { return _pos; };
+ void stop();
signals:
void finished( NSPluginStreamBase *strm );
@@ -150,6 +151,7 @@ public:
// constructor, destructor
NSPluginInstance( NPP privateData, NPPluginFuncs *pluginFuncs, KLibrary *handle,
int width, int height, QString src, QString mime,
+ QString appId, QString callbackId,
QObject *parent, const char* name=0 );
~NSPluginInstance();
@@ -158,7 +160,6 @@ public:
int winId() { return XtWindow(_toplevel); };
int setWindow(int remove=0);
void resizePlugin(int w, int h);
- void setCallback( QCString app, QCString obj );
// value handling
NPError NPGetValue(NPPVariable variable, void *value);
@@ -237,7 +238,8 @@ public:
QString getMIMEDescription();
DCOPRef newInstance(QString url, QString mimeType, bool embed,
- QStringList argn, QStringList argv);
+ QStringList argn, QStringList argv,
+ QString appId, QString callbackId );
void destroyInstance( NSPluginInstance* inst );
bool error() { return _error; };
Index: viewer/viewer.cpp
===================================================================
RCS file: /home/kde/kdebase/nsplugins/viewer/viewer.cpp,v
retrieving revision 1.18
diff -u -p -B -w -r1.18 viewer.cpp
--- viewer/viewer.cpp 2000/09/03 19:10:08 1.18
+++ viewer/viewer.cpp 2001/01/25 17:43:35
@@ -31,7 +31,7 @@
#include <kcmdlineargs.h>
#include <dcopclient.h>
#include <klocale.h>
-#include <qintdict.h>
+#include <qlist.h>
#include <qsocketnotifier.h>
#include <stdlib.h>
#include "../../config.h"
@@ -96,17 +96,13 @@ void parseCommandLine(int argc, char *ar
struct SocketNot
{
- int sock;
- int type;
+ int fd;
QObject *obj;
XtInputId id;
};
-QIntDict<SocketNot> _read_notifiers;
-QIntDict<SocketNot> _write_notifiers;
-QIntDict<SocketNot> _except_notifiers;
+QList<SocketNot> _notifiers[3];
-
/**
* socketCallback - send event to the socket notifier
*
@@ -135,55 +131,58 @@ bool qt_set_socket_handler( int sockfd,
{
kdDebug(1430) << "-> qt_set_socket_handler( sockfd=" << sockfd << ", type=" << \
type << ", obj=" << obj << ", enable=" << enable << " )" << endl;
- if ( sockfd < 0 || type < 0 || type > 2 || obj == 0 )
- {
+ if ( sockfd < 0 || type < 0 || type > 2 || obj == 0 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QSocketNotifier: Internal error" );
+#endif
return FALSE;
}
- SocketNot *socknot = 0;
- QIntDict<SocketNot> *notifiers;
XtPointer inpMask = 0;
- switch (type)
- {
- case QSocketNotifier::Read:
- inpMask = (XtPointer)XtInputReadMask;
- notifiers = &_read_notifiers;
- break;
- case QSocketNotifier::Write:
- inpMask = (XtPointer)XtInputWriteMask;
- notifiers = &_write_notifiers;
- break;
- case QSocketNotifier::Exception:
- inpMask = (XtPointer)XtInputExceptMask;
- notifiers = &_except_notifiers;
- break;
+ switch (type) {
+ case QSocketNotifier::Read: inpMask = (XtPointer)XtInputReadMask; break;
+ case QSocketNotifier::Write: inpMask = (XtPointer)XtInputWriteMask; break;
+ case QSocketNotifier::Exception: inpMask = (XtPointer)XtInputExceptMask; break;
default: return FALSE;
}
- socknot = notifiers->find( sockfd );
- if (enable)
- {
- if (!socknot)
- {
- socknot = new SocketNot;
- } else
- {
- XtRemoveInput( socknot->id );
- notifiers->remove( socknot->sock );
- }
+ if (enable) {
+ SocketNot *sn = new SocketNot;
+ sn->obj = obj;
+ sn->fd = sockfd;
+
+ if( _notifiers[type].isEmpty() ) {
+ _notifiers[type].insert( 0, sn );
+ } else {
+ SocketNot *p = _notifiers[type].first();
+ while ( p && p->fd > sockfd )
+ p = _notifiers[type].next();
+
+#if defined(CHECK_STATE)
+ if ( p && p->fd==sockfd ) {
+ static const char *t[] = { "read", "write", "exception" };
+ qWarning( "QSocketNotifier: Multiple socket notifiers for "
+ "same socket %d and type %s", sockfd, t[type] );
+ }
+#endif
+ if ( p )
+ _notifiers[type].insert( _notifiers[type].at(), sn );
+ else
+ _notifiers[type].append( sn );
+ }
+
+ sn->id = XtAppAddInput( g_appcon, sockfd, inpMask, socketCallback, sn );
+
+ } else {
+
+ SocketNot *sn = _notifiers[type].first();
+ while ( sn && !(sn->obj == obj && sn->fd == sockfd) )
+ sn = _notifiers[type].next();
+ if ( !sn ) // not found
+ return FALSE;
- socknot->sock = sockfd;
- socknot->type = type;
- socknot->obj = obj;
- socknot->id = XtAppAddInput( g_appcon, sockfd, inpMask, socketCallback, socknot \
);
- notifiers->insert( sockfd, socknot );
- } else
- if (socknot)
- {
- XtRemoveInput( socknot->id );
- notifiers->remove( socknot->sock );
- delete socknot;
+ XtRemoveInput( sn->id );
}
kdDebug(1430) << "<- qt_set_socket_handler" << endl;
@@ -205,7 +204,12 @@ int main(int argc, char** argv)
kdDebug(1430) << "2 - XtToolkitInitialize" << endl;
XtToolkitInitialize();
g_appcon = XtCreateApplicationContext();
- Display *dpy = XtOpenDisplay(g_appcon, NULL, "nspluginviewer", "nspluginviewer", \
0, 0, &argc, argv); + Display *dpy = XtOpenDisplay(g_appcon, NULL, \
"nspluginviewer", "nspluginviewer", + 0, 0, &argc, \
argv); +
+ _notifiers[0].setAutoDelete( TRUE );
+ _notifiers[1].setAutoDelete( TRUE );
+ _notifiers[2].setAutoDelete( TRUE );
kdDebug(1430) << "3 - parseCommandLine" << endl;
parseCommandLine(argc, argv);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic