浏览代码

Merge branch 'memhandling'

Sascha Zelzer 15 年之前
父节点
当前提交
a75f212fc3
共有 30 个文件被更改,包括 212 次插入153 次删除
  1. 2 1
      Libs/PluginFramework/Testing/Cpp/ctkPluginFrameworkTestMain.cpp
  2. 5 5
      Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite.cpp
  3. 2 2
      Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite_p.h
  4. 5 5
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/CMakeLists.txt
  5. 5 8
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA.cpp
  6. 5 5
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAActivator.cpp
  7. 6 6
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAActivator_p.h
  8. 6 6
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAService.h
  9. 11 9
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA_p.h
  10. 2 2
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/manifest_headers.cmake
  11. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginSL4_test/ctkActivator.cpp
  12. 1 4
      Libs/PluginFramework/ctkPlugin.cpp
  13. 2 2
      Libs/PluginFramework/ctkPluginContext.cpp
  14. 4 5
      Libs/PluginFramework/ctkPluginContext.h
  15. 5 0
      Libs/PluginFramework/ctkPluginFrameworkListeners.cpp
  16. 11 6
      Libs/PluginFramework/ctkPluginPrivate.cpp
  17. 2 1
      Libs/PluginFramework/ctkPluginStorage.cpp
  18. 1 1
      Libs/PluginFramework/ctkServiceReference.cpp
  19. 2 0
      Libs/PluginFramework/ctkServiceReference.h
  20. 1 1
      Libs/PluginFramework/ctkServiceReferencePrivate.h
  21. 48 3
      Libs/PluginFramework/ctkServiceRegistration.cpp
  22. 25 11
      Libs/PluginFramework/ctkServiceRegistration.h
  23. 1 1
      Libs/PluginFramework/ctkServiceRegistrationPrivate.cpp
  24. 5 0
      Libs/PluginFramework/ctkServiceRegistrationPrivate.h
  25. 4 12
      Libs/PluginFramework/ctkServiceTracker.h
  26. 1 4
      Libs/PluginFramework/ctkServiceTrackerPrivate.tpp
  27. 35 37
      Libs/PluginFramework/ctkServices.cpp
  28. 8 8
      Libs/PluginFramework/ctkServices_p.h
  29. 4 5
      Plugins/org.commontk.qtmobility.service/ctkQtMobilityServiceRuntime.cpp
  30. 2 2
      Plugins/org.commontk.qtmobility.service/ctkQtMobilityServiceRuntime_p.h

+ 2 - 1
Libs/PluginFramework/Testing/Cpp/ctkPluginFrameworkTestMain.cpp

@@ -58,7 +58,7 @@ public:
       if (result > 0) break;
     }
 
-    QCoreApplication::exit(result);
+    if (result > 0) QCoreApplication::exit(result);
   }
 
 private:
@@ -132,6 +132,7 @@ int main(int argc, char** argv)
 //  return result;
 
   TestRunner runner(context, fwTestPluginId, argc, argv);
+  runner.connect(&runner, SIGNAL(finished()), &app, SLOT(quit()));
   runner.start();
 
   return app.exec();

+ 5 - 5
Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite.cpp

@@ -393,8 +393,8 @@ bool ctkServiceListenerTestSuite::runStartStopTest(
   return teststatus;
 }
 
-ctkServiceListener::ctkServiceListener(ctkPluginContext* pc, bool checkUsingBundles)
-  : checkUsingBundles(checkUsingBundles), teststatus(true), pc(pc)
+ctkServiceListener::ctkServiceListener(ctkPluginContext* pc, bool checkUsingPlugins)
+  : checkUsingPlugins(checkUsingPlugins), teststatus(true), pc(pc)
 {
 
 }
@@ -433,7 +433,7 @@ void ctkServiceListener::serviceChanged(const ctkServiceEvent& evt)
 
     // Validate that no bundle is marked as using the service
     QList<QSharedPointer<ctkPlugin> > usingPlugins = sr.getUsingPlugins();
-    if (checkUsingBundles && !usingPlugins.isEmpty())
+    if (checkUsingPlugins && !usingPlugins.isEmpty())
     {
       teststatus = false;
       printUsingPlugins(sr, "*** Using plugins (unreg) should be empty but is: ");
@@ -452,7 +452,7 @@ void ctkServiceListener::serviceChanged(const ctkServiceEvent& evt)
                  << "while handling unregistering event.";
       }
       qDebug() << "Service (unreg): " << service->metaObject()->className();
-      if (checkUsingBundles && usingPlugins.size() != 1)
+      if (checkUsingPlugins && usingPlugins.size() != 1)
       {
         teststatus = false;
         printUsingPlugins(sr, "*** One using plugin expected "
@@ -524,7 +524,7 @@ void ctkServiceListener::printUsingPlugins(const ctkServiceReference& sr,
   qDebug() << (caption.isEmpty() ? "Using plugins: " : caption);
   foreach(QSharedPointer<ctkPlugin> plugin, usingPlugins)
   {
-    qDebug() << "  -" << plugin;
+    qDebug() << "  -" << plugin.data();
   }
 }
 

+ 2 - 2
Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite_p.h

@@ -87,7 +87,7 @@ private:
 
   friend class ctkServiceListenerTestSuite;
 
-  const bool checkUsingBundles;
+  const bool checkUsingPlugins;
   QList<ctkServiceEvent> events;
 
   bool teststatus;
@@ -96,7 +96,7 @@ private:
 
 public:
 
-  ctkServiceListener(ctkPluginContext* pc, bool checkUsingBundles = true);
+  ctkServiceListener(ctkPluginContext* pc, bool checkUsingPlugins = true);
 
   void clearEvents();
 

+ 5 - 5
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/CMakeLists.txt

@@ -3,14 +3,14 @@ PROJECT(pluginA2_test)
 SET(PLUGIN_export_directive "pluginA2_test_EXPORT")
 
 SET(PLUGIN_SRCS
-  ctkTestPluginA.cpp
-  ctkTestPluginAActivator.cpp
-  ctkTestPluginAService.h
+  ctkTestPluginA2.cpp
+  ctkTestPluginA2Activator.cpp
+  ctkTestPluginA2Service.h
 )
 
 SET(PLUGIN_MOC_SRCS
-  ctkTestPluginA_p.h
-  ctkTestPluginAActivator_p.h
+  ctkTestPluginA2_p.h
+  ctkTestPluginA2Activator_p.h
 )
 
 SET(PLUGIN_resources

+ 5 - 8
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA.cpp

@@ -20,24 +20,21 @@
 =============================================================================*/
 
 
-#include "ctkTestPluginA_p.h"
+#include "ctkTestPluginA2_p.h"
 
 #include <ctkPluginContext.h>
-#include <ctkServiceRegistration.h>
 
 #include <QStringList>
 
-ctkTestPluginA::ctkTestPluginA(ctkPluginContext* pc)
+ctkTestPluginA2::ctkTestPluginA2(ctkPluginContext* pc)
 {
-  sr = pc->registerService<ctkTestPluginAService>(this);
+  sr = pc->registerService<ctkTestPluginA2Service>(this);
 }
 
-void ctkTestPluginA::unregister()
+void ctkTestPluginA2::unregister()
 {
   if (sr)
   {
-    sr->unregister();
+    sr.unregister();
   }
-  delete sr;
-  sr = 0;
 }

+ 5 - 5
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAActivator.cpp

@@ -20,21 +20,21 @@
 =============================================================================*/
 
 
-#include "ctkTestPluginAActivator_p.h"
+#include "ctkTestPluginA2Activator_p.h"
 
 #include <ctkPluginContext.h>
 
 #include <QtPlugin>
 
-void ctkTestPluginAActivator::start(ctkPluginContext* context)
+void ctkTestPluginA2Activator::start(ctkPluginContext* context)
 {
-  s.reset(new ctkTestPluginA(context));
+  s.reset(new ctkTestPluginA2(context));
 }
 
-void ctkTestPluginAActivator::stop(ctkPluginContext* context)
+void ctkTestPluginA2Activator::stop(ctkPluginContext* context)
 {
   Q_UNUSED(context)
   s->unregister();
 }
 
-Q_EXPORT_PLUGIN2(pluginA_test, ctkTestPluginAActivator)
+Q_EXPORT_PLUGIN2(pluginA2_test, ctkTestPluginA2Activator)

+ 6 - 6
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAActivator_p.h

@@ -19,16 +19,16 @@
 
 =============================================================================*/
 
-#ifndef CTKTESTPLUGINAACTIVATOR_P_H
-#define CTKTESTPLUGINAACTIVATOR_P_H
+#ifndef CTKTESTPLUGINA2ACTIVATOR_P_H
+#define CTKTESTPLUGINA2ACTIVATOR_P_H
 
 #include <QScopedPointer>
 
 #include <ctkPluginActivator.h>
 
-#include "ctkTestPluginA_p.h"
+#include "ctkTestPluginA2_p.h"
 
-class ctkTestPluginAActivator : public QObject,
+class ctkTestPluginA2Activator : public QObject,
                                 public ctkPluginActivator
 {
   Q_OBJECT
@@ -41,8 +41,8 @@ public:
 
 private:
 
-  QScopedPointer<ctkTestPluginA> s;
+  QScopedPointer<ctkTestPluginA2> s;
 
 };
 
-#endif // CTKTESTPLUGINAACTIVATOR_P_H
+#endif // CTKTESTPLUGINA2ACTIVATOR_P_H

+ 6 - 6
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAService.h

@@ -20,16 +20,16 @@
 =============================================================================*/
 
 
-#ifndef CTKTESTPLUGINASERVICE_H
-#define CTKTESTPLUGINASERVICE_H
+#ifndef CTKTESTPLUGINA2SERVICE_H
+#define CTKTESTPLUGINA2SERVICE_H
 
 #include <qglobal.h>
 
-struct ctkTestPluginAService
+struct ctkTestPluginA2Service
 {
-  virtual ~ctkTestPluginAService() {}
+  virtual ~ctkTestPluginA2Service() {}
 };
 
-Q_DECLARE_INTERFACE(ctkTestPluginAService, "org.commontk.pluginA2test.TestPluginAService")
+Q_DECLARE_INTERFACE(ctkTestPluginA2Service, "org.commontk.pluginA2test.TestPluginA2Service")
 
-#endif // CTKTESTPLUGINASERVICE_H
+#endif // CTKTESTPLUGINA2SERVICE_H

+ 11 - 9
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA_p.h

@@ -20,30 +20,32 @@
 =============================================================================*/
 
 
-#ifndef CTKTESTPLUGINA_P_H
-#define CTKTESTPLUGINA_P_H
+#ifndef CTKTESTPLUGINA2_P_H
+#define CTKTESTPLUGINA2_P_H
 
 #include <QObject>
 
-#include "ctkTestPluginAService.h"
+#include "ctkTestPluginA2Service.h"
+
+#include <ctkServiceRegistration.h>
 
 class ctkPluginContext;
 class ctkServiceRegistration;
 
-class ctkTestPluginA : public QObject,
-                       public ctkTestPluginAService
+class ctkTestPluginA2 : public QObject,
+                       public ctkTestPluginA2Service
 {
   Q_OBJECT
-  Q_INTERFACES(ctkTestPluginAService)
+  Q_INTERFACES(ctkTestPluginA2Service)
 
 public:
-  ctkTestPluginA(ctkPluginContext* pc);
+  ctkTestPluginA2(ctkPluginContext* pc);
 
   void unregister();
 
 private:
 
-  ctkServiceRegistration* sr;
+  ctkServiceRegistration sr;
 };
 
-#endif // CTKTESTPLUGINA_P_H
+#endif // CTKTESTPLUGINA2_P_H

+ 2 - 2
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/manifest_headers.cmake

@@ -1,7 +1,7 @@
 set(Plugin-ActivationPolicy "eager")
-set(Plugin-Name "pluginA_test")
+set(Plugin-Name "pluginA2_test")
 set(Plugin-Version "1.0.0")
-set(Plugin-Description "Test plugin for framework, pluginA_test")
+set(Plugin-Description "Test plugin for framework, pluginA2_test")
 set(Plugin-Vendor "CommonTK")
 set(Plugin-ContactAddress "http://www.commontk.org")
 set(Plugin-Category "test")

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginSL4_test/ctkActivator.cpp

@@ -33,7 +33,7 @@ void ctkActivator::foo()
 
 void ctkActivator::start(ctkPluginContext* context)
 {
-  ctkServiceRegistration* registration =
+  ctkServiceRegistration registration =
       context->registerService<ctkFooService>(this);
   qDebug() << "pluginSL4: Registered" << registration;
 }

+ 1 - 4
Libs/PluginFramework/ctkPlugin.cpp

@@ -21,6 +21,7 @@
 
 #include "ctkPlugin.h"
 
+#include "ctkPluginContext.h"
 #include "ctkPluginFrameworkUtil_p.h"
 #include "ctkPluginPrivate_p.h"
 #include "ctkPluginArchive_p.h"
@@ -153,10 +154,6 @@ void ctkPlugin::stop(const StopOptions& options)
     break;
   };
 
-  if (d->state != UNINSTALLED)
-  {
-    d->fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, d->q_ptr));
-  }
   if (savedException)
   {
     if (const ctkPluginException* pluginExc = dynamic_cast<const ctkPluginException*>(savedException))

+ 2 - 2
Libs/PluginFramework/ctkPluginContext.cpp

@@ -109,14 +109,14 @@ QFileInfo ctkPluginContext::getDataFile(const QString& filename)
   return QFileInfo(dataRoot, filename);
 }
 
-ctkServiceRegistration* ctkPluginContext::registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties)
+ctkServiceRegistration ctkPluginContext::registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties)
 {
   Q_D(ctkPluginContext);
   d->isPluginContextValid();
   return d->plugin->fwCtx->services->registerService(d->plugin, clazzes, service, properties);
 }
 
-ctkServiceRegistration* ctkPluginContext::registerService(const char* clazz, QObject* service, const ServiceProperties& properties)
+ctkServiceRegistration ctkPluginContext::registerService(const char* clazz, QObject* service, const ServiceProperties& properties)
 {
   Q_D(ctkPluginContext);
   d->isPluginContextValid();

+ 4 - 5
Libs/PluginFramework/ctkPluginContext.h

@@ -34,6 +34,7 @@
 #include "ctkPluginEvent.h"
 #include "ctkServiceException.h"
 #include "ctkServiceReference.h"
+#include "ctkServiceRegistration.h"
 
 #include "ctkPluginFrameworkExport.h"
 
@@ -41,7 +42,6 @@
 // CTK class forward declarations
 class ctkPlugin;
 class ctkPluginPrivate;
-class ctkServiceRegistration;
 class ctkPluginContextPrivate;
 
 /**
@@ -211,7 +211,7 @@ public:
    * @see ctkServiceRegistration
    * @see ctkServiceFactory
    */
-  ctkServiceRegistration* registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties = ServiceProperties());
+  ctkServiceRegistration registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties = ServiceProperties());
 
   /**
    * Registers the specified service object with the specified properties
@@ -234,10 +234,10 @@ public:
    * @throws std::logic_error If this ctkPluginContext is no longer valid.
    * @see registerService(const QStringList&, QObject*, const ServiceProperties&)
    */
-  ctkServiceRegistration* registerService(const char* clazz, QObject* service, const ServiceProperties& properties = ServiceProperties());
+  ctkServiceRegistration registerService(const char* clazz, QObject* service, const ServiceProperties& properties = ServiceProperties());
 
   template<class S>
-  ctkServiceRegistration* registerService(QObject* service, const ServiceProperties& properties = ServiceProperties())
+  ctkServiceRegistration registerService(QObject* service, const ServiceProperties& properties = ServiceProperties())
   {
     const char* clazz = qobject_interface_iid<S*>();
     if (clazz == 0)
@@ -665,7 +665,6 @@ public:
    * @param receiver The object to connect to.
    * @param slot The name of the slot to be connected.
    * @param filter The filter criteria.
-   * @param type The Qt connection type.
    * @throws std::invalid_argument If <code>filter</code> contains an
    *         invalid filter string that cannot be parsed.
    * @throws std::logic_error If this ctkPluginContext is no

+ 5 - 0
Libs/PluginFramework/ctkPluginFrameworkListeners.cpp

@@ -80,6 +80,11 @@ void ctkPluginFrameworkListeners::removeServiceSlot(ctkPlugin* plugin,
       if (slot) break;
     }
   }
+
+  if (plugin)
+  {
+    disconnect(receiver, SIGNAL(destroyed(QObject*)), this, SLOT(serviceListenerDestroyed(QObject*)));
+  }
 }
 
 void ctkPluginFrameworkListeners::serviceListenerDestroyed(QObject *listener)

+ 11 - 6
Libs/PluginFramework/ctkPluginPrivate.cpp

@@ -274,6 +274,7 @@ void ctkPluginPrivate::stop0(bool wasStarted)
   state = ctkPlugin::STOPPING;
   deactivating = true;
   //6-13:
+  ctkPluginActivator* activator = 0;
   const std::exception* savedException = 0;
   try
   {
@@ -296,6 +297,7 @@ void ctkPluginPrivate::stop0(bool wasStarted)
       {
         throw std::logic_error("Plugin is uninstalled");
       }
+      activator = pluginActivator;
       pluginActivator = 0;
     }
 
@@ -316,11 +318,14 @@ void ctkPluginPrivate::stop0(bool wasStarted)
     savedException = exc;
   }
 
+  delete activator;
+
   if (state != ctkPlugin::UNINSTALLED)
   {
     state = ctkPlugin::RESOLVED;
     deactivating = false;
     //fwCtx.packages.notifyAll();
+    fwCtx->listeners.emitPluginChanged(ctkPluginEvent(ctkPluginEvent::STOPPED, q_func()));
   }
 
   if (savedException)
@@ -400,13 +405,13 @@ void ctkPluginPrivate::removePluginResources()
   // automatic disconnect due to Qt signal slot
   //fwCtx->listeners.removeAllListeners(this);
 
-  QList<ctkServiceRegistration*> srs = fwCtx->services->getRegisteredByPlugin(this);
-  QListIterator<ctkServiceRegistration*> i(srs);
+  QList<ctkServiceRegistration> srs = fwCtx->services->getRegisteredByPlugin(this);
+  QMutableListIterator<ctkServiceRegistration> i(srs);
   while (i.hasNext())
   {
     try
     {
-      i.next()->unregister();
+      i.next().unregister();
     }
     catch (const std::logic_error& /*ignore*/)
     {
@@ -416,11 +421,11 @@ void ctkPluginPrivate::removePluginResources()
     }
   }
 
-  QList<ctkServiceRegistration*> s = fwCtx->services->getUsedByPlugin(q_func());
-  QListIterator<ctkServiceRegistration*> i2(s);
+  QList<ctkServiceRegistration> s = fwCtx->services->getUsedByPlugin(q_func());
+  QListIterator<ctkServiceRegistration> i2(s);
   while (i2.hasNext())
   {
-    i2.next()->getReference().d_func()->ungetService(q_func(), false);
+    i2.next().getReference().d_func()->ungetService(q_func(), false);
   }
 
 }

+ 2 - 1
Libs/PluginFramework/ctkPluginStorage.cpp

@@ -114,12 +114,13 @@ QList<QString> ctkPluginStorage::getStartOnLaunchPlugins()
 ctkPluginStorage::~ctkPluginStorage()
 {
   close();
+  // ctkPluginArchive pointers in archives list are deleted
+  // in ~ctkPluginPrivate()
 }
 
 void ctkPluginStorage::close()
 {
   pluginDatabase.close();
-  //qDeleteAll(archives);
 }
 
 bool ctkPluginStorage::removeArchive(ctkPluginArchive* pa)

+ 1 - 1
Libs/PluginFramework/ctkServiceReference.cpp

@@ -131,7 +131,7 @@ ctkServiceReference& ctkServiceReference::operator=(const ctkServiceReference& r
 
 uint qHash(const ctkServiceReference& serviceRef)
 {
-  return qHash(serviceRef.getProperty(ctkPluginConstants::SERVICE_ID).toLongLong());
+  return qHash(serviceRef.d_func()->registration);
 }
 
 QDebug operator<<(QDebug dbg, const ctkServiceReference& serviceRef)

+ 2 - 0
Libs/PluginFramework/ctkServiceReference.h

@@ -183,6 +183,8 @@ protected:
   template<class S, class T> friend class ctkServiceTrackerPrivate;
   template<class S, class R, class T> friend class ctkPluginAbstractTracked;
 
+  friend uint qHash(const ctkServiceReference&);
+
   ctkServiceReference(ctkServiceRegistrationPrivate* reg);
 
   ctkServiceReferencePrivate * d_ptr;

+ 1 - 1
Libs/PluginFramework/ctkServiceReferencePrivate.h

@@ -77,7 +77,7 @@ public:
   /**
    * Link to registration object for this reference.
    */
-  ctkServiceRegistrationPrivate* registration;
+  ctkServiceRegistrationPrivate* const registration;
 };
 
 #endif // CTKSERVICEREFERENCEPRIVATE_H

+ 48 - 3
Libs/PluginFramework/ctkServiceRegistration.cpp

@@ -33,6 +33,17 @@
 
 #include <stdexcept>
 
+ctkServiceRegistration::ctkServiceRegistration()
+  : d_ptr(0)
+{
+
+}
+
+ctkServiceRegistration::ctkServiceRegistration(const ctkServiceRegistration& reg)
+  : d_ptr(reg.d_ptr)
+{
+  d_func()->ref.ref();
+}
 
 ctkServiceRegistration::ctkServiceRegistration(ctkPluginPrivate* plugin, QObject* service,
                     const ServiceProperties& props)
@@ -41,15 +52,22 @@ ctkServiceRegistration::ctkServiceRegistration(ctkPluginPrivate* plugin, QObject
 
 }
 
-ctkServiceRegistration::~ctkServiceRegistration()
+ctkServiceRegistration::operator bool() const
 {
+  return d_func();
+}
 
+ctkServiceRegistration::~ctkServiceRegistration()
+{
+  if (d_func() && !d_func()->ref.deref())
+    delete d_ptr;
 }
 
 ctkServiceReference ctkServiceRegistration::getReference() const
 {
   Q_D(const ctkServiceRegistration);
 
+  if (!d) throw std::logic_error("ctkServiceRegistration object invalid");
   if (!d->available) throw std::logic_error("Service is unregistered");
 
   return d->reference;
@@ -58,6 +76,8 @@ ctkServiceReference ctkServiceRegistration::getReference() const
 void ctkServiceRegistration::setProperties(const ServiceProperties& props)
 {
   Q_D(ctkServiceRegistration);
+  if (!d) throw std::logic_error("ctkServiceRegistration object invalid");
+
   QMutexLocker lock(&d->eventLock);
 
   QSet<ctkServiceSlotEntry> before;
@@ -77,7 +97,7 @@ void ctkServiceRegistration::setProperties(const ServiceProperties& props)
       int new_rank = d->properties.value(ctkPluginConstants::SERVICE_RANKING).toInt();
       if (old_rank != new_rank)
       {
-        d->plugin->fwCtx->services->updateServiceRegistrationOrder(this, classes);
+        d->plugin->fwCtx->services->updateServiceRegistrationOrder(*this, classes);
       }
     }
     else
@@ -97,6 +117,7 @@ void ctkServiceRegistration::setProperties(const ServiceProperties& props)
 void ctkServiceRegistration::unregister()
 {
   Q_D(ctkServiceRegistration);
+  if (!d) throw std::logic_error("ctkServiceRegistration object invalid");
 
   if (d->unregistering) return; // Silently ignore redundant unregistration.
   {
@@ -108,7 +129,7 @@ void ctkServiceRegistration::unregister()
     {
       if (d->plugin)
       {
-        d->plugin->fwCtx->services->removeServiceRegistration(this);
+        d->plugin->fwCtx->services->removeServiceRegistration(*this);
       }
     }
     else
@@ -161,5 +182,29 @@ void ctkServiceRegistration::unregister()
 bool ctkServiceRegistration::operator<(const ctkServiceRegistration& o) const
 {
   Q_D(const ctkServiceRegistration);
+  if (!d) return true;
   return d->reference <(o.d_func()->reference);
 }
+
+bool ctkServiceRegistration::operator==(const ctkServiceRegistration& registration) const
+{
+  Q_D(const ctkServiceRegistration);
+  return d == registration.d_func();
+}
+
+ctkServiceRegistration& ctkServiceRegistration::operator=(const ctkServiceRegistration& registration)
+{
+  ctkServiceRegistrationPrivate* curr_d = d_func();
+  d_ptr = registration.d_ptr;
+  d_ptr->ref.ref();
+
+  if (curr_d && !curr_d->ref.deref())
+    delete curr_d;
+
+  return *this;
+}
+
+uint qHash(const ctkServiceRegistration& serviceReg)
+{
+  return qHash(serviceReg.d_func());
+}

+ 25 - 11
Libs/PluginFramework/ctkServiceRegistration.h

@@ -22,8 +22,7 @@
 #ifndef CTKSERVICEREGISTRATION_H
 #define CTKSERVICEREGISTRATION_H
 
-#include "ctkPluginContext.h"
-
+#include "ctkPluginFramework_global.h"
 #include "ctkServiceReference.h"
 
 #include "ctkPluginFrameworkExport.h"
@@ -52,6 +51,17 @@ class CTK_PLUGINFW_EXPORT ctkServiceRegistration {
 
 public:
 
+  /**
+   * Creates an invalid ctkServiceRegistration object. You can use
+   * this object in boolean expressions and it will evaluate to
+   * <code>false</code>.
+   */
+  ctkServiceRegistration();
+
+  ctkServiceRegistration(const ctkServiceRegistration& reg);
+
+  operator bool() const;
+
   ~ctkServiceRegistration();
 
   /**
@@ -63,7 +73,7 @@ public:
    *
    * @throws std::logic_error If this
    *         <code>ctkServiceRegistration</code> object has already been
-   *         unregistered.
+   *         unregistered or if it is invalid.
    * @return <code>ctkServiceReference</code> object.
    */
   ctkServiceReference getReference() const;
@@ -89,7 +99,7 @@ public:
    *        service's properties this method should be called again.
    *
    * @throws std::logic_error If this <code>ctkServiceRegistration</code>
-   *         object has already been unregistered.
+   *         object has already been unregistered or if it is invalid.
    * @throws std::invalid_argument If <code>properties</code> contains
    *         case variants of the same key name.
    */
@@ -122,28 +132,32 @@ public:
    *
    * @throws std::logic_error If this
    *         <code>ctkServiceRegistration</code> object has already been
-   *         unregistered.
-   * @see BundleContext#ungetService
+   *         unregistered or if it is invalid.
+   * @see ctkPluginContext#ungetService
    * @see ctkServiceFactory#ungetService
    */
   virtual void unregister();
 
   bool operator<(const ctkServiceRegistration& o) const;
 
+  bool operator==(const ctkServiceRegistration& registration) const;
+
+  ctkServiceRegistration& operator=(const ctkServiceRegistration& registration);
+
+
 protected:
 
   friend class ctkServices;
 
+  friend uint qHash(const ctkServiceRegistration&);
+
   ctkServiceRegistration(ctkPluginPrivate* plugin, QObject* service,
                          const ServiceProperties& props);
 
-  const QScopedPointer<ctkServiceRegistrationPrivate> d_ptr;
-
-private:
-
-  Q_DISABLE_COPY(ctkServiceRegistration)
+  ctkServiceRegistrationPrivate* d_ptr;
 
 };
 
+uint CTK_PLUGINFW_EXPORT qHash(const ctkServiceRegistration& serviceRef);
 
 #endif // CTKSERVICEREGISTRATION_H

+ 1 - 1
Libs/PluginFramework/ctkServiceRegistrationPrivate.cpp

@@ -25,7 +25,7 @@
 ctkServiceRegistrationPrivate::ctkServiceRegistrationPrivate(ctkServiceRegistration* sr,
                                                        ctkPluginPrivate* plugin, QObject* service,
                                                        const ServiceProperties& props)
-                             : q_ptr(sr), service(service), plugin(plugin), reference(this),
+                             : q_ptr(sr), ref(1), service(service), plugin(plugin), reference(this),
                              properties(props), available(true), unregistering(false)
 {
 

+ 5 - 0
Libs/PluginFramework/ctkServiceRegistrationPrivate.h

@@ -41,6 +41,11 @@ protected:
   ctkServiceRegistration* const q_ptr;
 
   /**
+   * Reference count for implicitly shared private implementation.
+   */
+  QAtomicInt ref;
+
+  /**
    * Service or ctkServiceFactory object.
    */
   QObject* service;

+ 4 - 12
Libs/PluginFramework/ctkServiceTracker.h

@@ -93,9 +93,7 @@ public:
    *        <code>ctkServiceTracker</code> will be used as the
    *        <code>ctkServiceTrackerCustomizer</code> and this
    *        <code>ctkServiceTracker</code> will call the
-   *        <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
-   *        customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
-   *        takes ownership of the customizer.
+   *        <code>ctkServiceTrackerCustomizer</code> methods on itself.
    */
   ctkServiceTracker(ctkPluginContext* context,
                     const ctkServiceReference& reference,
@@ -117,9 +115,7 @@ public:
    *        <code>ctkServiceTracker</code> will be used as the
    *        <code>ctkServiceTrackerCustomizer</code> and this
    *        <code>ctkServiceTracker</code> will call the
-   *        <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
-   *        customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
-   *        takes ownership of the customizer.
+   *        <code>ctkServiceTrackerCustomizer</code> methods on itself.
    */
   ctkServiceTracker(ctkPluginContext* context, const QString& clazz,
                     ctkServiceTrackerCustomizer<T>* customizer = 0);
@@ -141,9 +137,7 @@ public:
    *        customizer is null, then this <code>ctkServiceTracker</code> will be
    *        used as the <code>ctkServiceTrackerCustomizer</code> and this
    *        <code>ctkServiceTracker</code> will call the
-   *        <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
-   *        customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
-   *        takes ownership of the customizer.
+   *        <code>ctkServiceTrackerCustomizer</code> methods on itself.
    */
   ctkServiceTracker(ctkPluginContext* context, const ctkLDAPSearchFilter& filter,
                     ctkServiceTrackerCustomizer<T>* customizer = 0);
@@ -163,9 +157,7 @@ public:
    *        customizer is null, then this <code>ctkServiceTracker</code> will be
    *        used as the <code>ctkServiceTrackerCustomizer</code> and this
    *        <code>ctkServiceTracker</code> will call the
-   *        <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
-   *        customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
-   *        takes ownership of the customizer.
+   *        <code>ctkServiceTrackerCustomizer</code> methods on itself.
    */
   ctkServiceTracker(ctkPluginContext* context, ctkServiceTrackerCustomizer<T>* customizer = 0);
 

+ 1 - 4
Libs/PluginFramework/ctkServiceTrackerPrivate.tpp

@@ -104,10 +104,7 @@ ctkServiceTrackerPrivate<S,T>::ctkServiceTrackerPrivate(
 template<class S, class T>
 ctkServiceTrackerPrivate<S,T>::~ctkServiceTrackerPrivate()
 {
-  if (customizer != q_func())
-  {
-    delete customizer;
-  }
+
 }
 
 template<class S, class T>

+ 35 - 37
Libs/PluginFramework/ctkServices.cpp

@@ -37,9 +37,9 @@
 
 struct ServiceRegistrationComparator
 {
-  bool operator()(const ctkServiceRegistration* a, const ctkServiceRegistration* b) const
+  bool operator()(const ctkServiceRegistration& a, const ctkServiceRegistration& b) const
   {
-    return *a < *b;
+    return a < b;
   }
 };
 
@@ -91,14 +91,12 @@ ctkServices::~ctkServices()
 
 void ctkServices::clear()
 {
-  QList<ctkServiceRegistration*> serviceRegs = services.keys();
-  qDeleteAll(serviceRegs);
   services.clear();
   classServices.clear();
   framework = 0;
 }
 
-ctkServiceRegistration* ctkServices::registerService(ctkPluginPrivate* plugin,
+ctkServiceRegistration ctkServices::registerService(ctkPluginPrivate* plugin,
                              const QStringList& classes,
                              QObject* service,
                              const ServiceProperties& properties)
@@ -128,22 +126,22 @@ ctkServiceRegistration* ctkServices::registerService(ctkPluginPrivate* plugin,
     }
   }
 
-  ctkServiceRegistration* res = new ctkServiceRegistration(plugin, service,
-                                createServiceProperties(properties, classes));
+  ctkServiceRegistration res(plugin, service,
+                             createServiceProperties(properties, classes));
   {
     QMutexLocker lock(&mutex);
     services.insert(res, classes);
     for (QStringListIterator i(classes); i.hasNext(); )
     {
       QString currClass = i.next();
-      QList<ctkServiceRegistration*>& s = classServices[currClass];
-      QList<ctkServiceRegistration*>::iterator ip =
+      QList<ctkServiceRegistration>& s = classServices[currClass];
+      QList<ctkServiceRegistration>::iterator ip =
           std::lower_bound(s.begin(), s.end(), res, ServiceRegistrationComparator());
       s.insert(ip, res);
     }
   }
 
-  ctkServiceReference r = res->getReference();
+  ctkServiceReference r = res.getReference();
   plugin->fwCtx->listeners.serviceChanged(
       plugin->fwCtx->listeners.getMatchingServiceSlots(r),
       ctkServiceEvent(ctkServiceEvent::REGISTERED, r));
@@ -151,13 +149,13 @@ ctkServiceRegistration* ctkServices::registerService(ctkPluginPrivate* plugin,
 }
 
 
-void ctkServices::updateServiceRegistrationOrder(ctkServiceRegistration* sr,
+void ctkServices::updateServiceRegistrationOrder(const ctkServiceRegistration& sr,
                                               const QStringList& classes)
 {
   QMutexLocker lock(&mutex);
   for (QStringListIterator i(classes); i.hasNext(); )
   {
-    QList<ctkServiceRegistration*>& s = classServices[i.next()];
+    QList<ctkServiceRegistration>& s = classServices[i.next()];
     s.removeAll(sr);
     s.insert(std::lower_bound(s.begin(), s.end(), sr, ServiceRegistrationComparator()), sr);
   }
@@ -169,7 +167,7 @@ bool ctkServices::checkServiceClass(QObject* service, const QString& cls) const
 }
 
 
-QList<ctkServiceRegistration*> ctkServices::get(const QString& clazz) const
+QList<ctkServiceRegistration> ctkServices::get(const QString& clazz) const
 {
   QMutexLocker lock(&mutex);
   return classServices.value(clazz);
@@ -199,8 +197,8 @@ QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString&
 {
   QMutexLocker lock(&mutex);
 
-  QListIterator<ctkServiceRegistration*>* s = 0;
-  QList<ctkServiceRegistration*> v;
+  QListIterator<ctkServiceRegistration>* s = 0;
+  QList<ctkServiceRegistration> v;
   ctkLDAPExpr ldap;
   if (clazz.isEmpty())
   {
@@ -213,12 +211,12 @@ QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString&
         v.clear();
         foreach (QString className, matched)
         {
-          const QList<ctkServiceRegistration*>& cl = classServices[className];
+          const QList<ctkServiceRegistration>& cl = classServices[className];
           v += cl;
         }
         if (!v.isEmpty())
         {
-          s = new QListIterator<ctkServiceRegistration*>(v);
+          s = new QListIterator<ctkServiceRegistration>(v);
         }
         else
         {
@@ -227,20 +225,20 @@ QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString&
       }
       else
       {
-        s = new QListIterator<ctkServiceRegistration*>(services.keys());
+        s = new QListIterator<ctkServiceRegistration>(services.keys());
       }
     }
     else
     {
-      s = new QListIterator<ctkServiceRegistration*>(services.keys());
+      s = new QListIterator<ctkServiceRegistration>(services.keys());
     }
   }
   else
   {
-    QList<ctkServiceRegistration*> v = classServices.value(clazz);
+    QList<ctkServiceRegistration> v = classServices.value(clazz);
     if (!v.isEmpty())
     {
-      s = new QListIterator<ctkServiceRegistration*>(v);
+      s = new QListIterator<ctkServiceRegistration>(v);
     }
     else
     {
@@ -255,10 +253,10 @@ QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString&
   QList<ctkServiceReference> res;
   while (s->hasNext())
   {
-    ctkServiceRegistration* sr = s->next();
-    ctkServiceReference sri = sr->getReference();
+    ctkServiceRegistration sr = s->next();
+    ctkServiceReference sri = sr.getReference();
 
-    if (filter.isEmpty() || ldap.evaluate(sr->d_func()->properties, false))
+    if (filter.isEmpty() || ldap.evaluate(sr.d_func()->properties, false))
     {
       res.push_back(sri);
     }
@@ -270,16 +268,16 @@ QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString&
 }
 
 
-void ctkServices::removeServiceRegistration(ctkServiceRegistration* sr)
+void ctkServices::removeServiceRegistration(const ctkServiceRegistration& sr)
 {
   QMutexLocker lock(&mutex);
 
-  QStringList classes = sr->d_func()->properties.value(ctkPluginConstants::OBJECTCLASS).toStringList();
+  QStringList classes = sr.d_func()->properties.value(ctkPluginConstants::OBJECTCLASS).toStringList();
   services.remove(sr);
   for (QStringListIterator i(classes); i.hasNext(); )
   {
     QString currClass = i.next();
-    QList<ctkServiceRegistration*>& s = classServices[currClass];
+    QList<ctkServiceRegistration>& s = classServices[currClass];
     if (s.size() > 1)
     {
       s.removeAll(sr);
@@ -292,15 +290,15 @@ void ctkServices::removeServiceRegistration(ctkServiceRegistration* sr)
 }
 
 
-QList<ctkServiceRegistration*> ctkServices::getRegisteredByPlugin(ctkPluginPrivate* p) const
+QList<ctkServiceRegistration> ctkServices::getRegisteredByPlugin(ctkPluginPrivate* p) const
 {
   QMutexLocker lock(&mutex);
 
-  QList<ctkServiceRegistration*> res;
-  for (QHashIterator<ctkServiceRegistration*, QStringList> i(services); i.hasNext(); )
+  QList<ctkServiceRegistration> res;
+  for (QHashIterator<ctkServiceRegistration, QStringList> i(services); i.hasNext(); )
   {
-    ctkServiceRegistration* sr = i.next().key();
-    if ((sr->d_func()->plugin == p))
+    ctkServiceRegistration sr = i.next().key();
+    if ((sr.d_func()->plugin == p))
     {
       res.push_back(sr);
     }
@@ -309,15 +307,15 @@ QList<ctkServiceRegistration*> ctkServices::getRegisteredByPlugin(ctkPluginPriva
 }
 
 
-QList<ctkServiceRegistration*> ctkServices::getUsedByPlugin(QSharedPointer<ctkPlugin> p) const
+QList<ctkServiceRegistration> ctkServices::getUsedByPlugin(QSharedPointer<ctkPlugin> p) const
 {
   QMutexLocker lock(&mutex);
 
-  QList<ctkServiceRegistration*> res;
-  for (QHashIterator<ctkServiceRegistration*, QStringList> i(services); i.hasNext(); )
+  QList<ctkServiceRegistration> res;
+  for (QHashIterator<ctkServiceRegistration, QStringList> i(services); i.hasNext(); )
   {
-    ctkServiceRegistration* sr = i.next().key();
-    if (sr->d_func()->isUsedByPlugin(p))
+    ctkServiceRegistration sr = i.next().key();
+    if (sr.d_func()->isUsedByPlugin(p))
     {
       res.push_back(sr);
     }

+ 8 - 8
Libs/PluginFramework/ctkServices_p.h

@@ -60,14 +60,14 @@ public:
    * Mapping of registered service to class names under which
    * the service is registerd.
    */
-  QHash<ctkServiceRegistration*, QStringList> services;
+  QHash<ctkServiceRegistration, QStringList> services;
 
   /**
    * Mapping of classname to registered service.
    * The List of registered services are ordered with the highest
    * ranked service first.
    */
-  QHash<QString, QList<ctkServiceRegistration*> > classServices;
+  QHash<QString, QList<ctkServiceRegistration> > classServices;
 
 
   ctkPluginFrameworkContext* framework;
@@ -93,7 +93,7 @@ public:
    * instance of all the named classes in the classes parameter.</li>
    * </ul>
    */
-  ctkServiceRegistration* registerService(ctkPluginPrivate* plugin,
+  ctkServiceRegistration registerService(ctkPluginPrivate* plugin,
                                const QStringList& classes,
                                QObject* service,
                                const ServiceProperties& properties);
@@ -106,7 +106,7 @@ public:
    * @param serviceRegistration The ctkServiceRegistrationPrivate object.
    * @param rank New rank of object.
    */
-  void updateServiceRegistrationOrder(ctkServiceRegistration* sr,
+  void updateServiceRegistrationOrder(const ctkServiceRegistration& sr,
                                       const QStringList& classes);
 
 
@@ -127,7 +127,7 @@ public:
    * @param clazz The class name of the requested service.
    * @return A sorted list of {@link ctkServiceRegistrationPrivate} objects.
    */
-  QList<ctkServiceRegistration*> get(const QString& clazz) const;
+  QList<ctkServiceRegistration> get(const QString& clazz) const;
 
 
   /**
@@ -159,7 +159,7 @@ public:
    *
    * @param sr The ctkServiceRegistration object that is registered.
    */
-  void removeServiceRegistration(ctkServiceRegistration* sr) ;
+  void removeServiceRegistration(const ctkServiceRegistration& sr) ;
 
 
   /**
@@ -168,7 +168,7 @@ public:
    * @param p The plugin
    * @return A set of {@link ctkServiceRegistration} objects
    */
-  QList<ctkServiceRegistration*> getRegisteredByPlugin(ctkPluginPrivate* p) const;
+  QList<ctkServiceRegistration> getRegisteredByPlugin(ctkPluginPrivate* p) const;
 
 
   /**
@@ -177,7 +177,7 @@ public:
    * @param p The plugin
    * @return A set of {@link ctkServiceRegistration} objects
    */
-  QList<ctkServiceRegistration*> getUsedByPlugin(QSharedPointer<ctkPlugin> p) const;
+  QList<ctkServiceRegistration> getUsedByPlugin(QSharedPointer<ctkPlugin> p) const;
 
 };
 

+ 4 - 5
Plugins/org.commontk.qtmobility.service/ctkQtMobilityServiceRuntime.cpp

@@ -165,7 +165,7 @@ void ctkQtMobilityServiceRuntime::processPlugin(QSharedPointer<ctkPlugin> plugin
       }
 
       ctkQtMobilityServiceFactory* serviceObject = new ctkQtMobilityServiceFactory(descr, this, plugin);
-      ctkServiceRegistration* serviceReg = plugin->getPluginContext()->registerService(classes, serviceObject, props);
+      ctkServiceRegistration serviceReg = plugin->getPluginContext()->registerService(classes, serviceObject, props);
 
       if (serviceReg)
       {
@@ -189,16 +189,15 @@ void ctkQtMobilityServiceRuntime::removePlugin(QSharedPointer<ctkPlugin> plugin)
       << "Remove " << plugin->getSymbolicName() << " from QtMobSR";
 
   QList<ctkQtMobilityServiceFactory*> serviceFactories = mapPluginToServiceFactory.values(plugin);
-  QList<ctkServiceRegistration*> serviceRegs = mapPluginToServiceRegistration.values(plugin);
-  foreach(ctkServiceRegistration* serviceReg, serviceRegs)
+  QList<ctkServiceRegistration> serviceRegs = mapPluginToServiceRegistration.values(plugin);
+  foreach(ctkServiceRegistration serviceReg, serviceRegs)
   {
-    serviceReg->unregister();
+    serviceReg.unregister();
   }
 
   mapPluginToServiceRegistration.remove(plugin);
   mapPluginToServiceFactory.remove(plugin);
 
-  qDeleteAll(serviceRegs);
   qDeleteAll(serviceFactories);
 }
 

+ 2 - 2
Plugins/org.commontk.qtmobility.service/ctkQtMobilityServiceRuntime_p.h

@@ -28,9 +28,9 @@
 
 #include <ctkPluginEvent.h>
 #include <ctkPlugin.h>
+#include <ctkServiceRegistration.h>
 
 class ctkPluginContext;
-class ctkServiceRegistration;
 class ctkQtMobilityServiceFactory;
 
 using namespace QtMobility;
@@ -57,7 +57,7 @@ private:
   QtMobility::QServiceManager qServiceManager;
 
   QMultiHash<QSharedPointer<ctkPlugin>, ctkQtMobilityServiceFactory*> mapPluginToServiceFactory;
-  QMultiHash<QSharedPointer<ctkPlugin>, ctkServiceRegistration*> mapPluginToServiceRegistration;
+  QMultiHash<QSharedPointer<ctkPlugin>, ctkServiceRegistration> mapPluginToServiceRegistration;
   QSet<QSharedPointer<ctkPlugin> > lazy;
 
   ctkPluginContext* pc;