[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