Explorar el Código

ENH: PluginFramework: Changed memory management of ctkServiceReference

ctkServiceReference objects are now implicitly shared.
Sascha Zelzer hace 15 años
padre
commit
a138c16913

+ 18 - 10
Applications/ctkPluginBrowser/ctkPluginBrowser.cpp

@@ -25,6 +25,7 @@
 #include "ctkPluginResourcesTreeModel.h"
 #include "ctkQtResourcesTreeModel.h"
 #include "ctkServiceReference.h"
+#include "ctkServiceException.h"
 #include "ctkPluginConstants.h"
 
 #include <ui_ctkPluginBrowserMainWindow.h>
@@ -112,20 +113,27 @@ void ctkPluginBrowser::pluginDoubleClicked(const QModelIndex& index)
   QString location = QString("/") + plugin->getSymbolicName() + "/META-INF/MANIFEST.MF";
   editors->openEditor(location, mfContent, location + " [cached]");
 
-  QList<ctkServiceReference*> serviceRefs = plugin->getPluginContext()->getServiceReferences("");
-  QListIterator<ctkServiceReference*> it(serviceRefs);
+  QList<ctkServiceReference> serviceRefs = plugin->getPluginContext()->getServiceReferences("");
+  QListIterator<ctkServiceReference> it(serviceRefs);
   while (it.hasNext())
   {
-    ctkServiceReference* ref = it.next();
-    qDebug() << "Service from" << ref->getPlugin()->getSymbolicName() << ":" << ref->getPropertyKeys();
-    qDebug() << "Object Classes:" << ref->getProperty(PluginConstants::OBJECTCLASS).toStringList();
+    ctkServiceReference ref(it.next());
+    qDebug() << "Service from" << ref.getPlugin()->getSymbolicName() << ":" << ref.getPropertyKeys();
+    qDebug() << "Object Classes:" << ref.getProperty(PluginConstants::OBJECTCLASS).toStringList();
   }
 
-  ctkServiceReference* cliRef = plugin->getPluginContext()->getServiceReference("ctkICLIManager");
-  QObject* cliService = plugin->getPluginContext()->getService(cliRef);
-  if (cliService)
-    qDebug() << "Got service object: " << cliService->metaObject()->className();
-  else qDebug() << "Got null service";
+  try
+  {
+    ctkServiceReference cliRef(plugin->getPluginContext()->getServiceReference("ctkICLIManager"));
+    QObject* cliService = plugin->getPluginContext()->getService(cliRef);
+    if (cliService)
+      qDebug() << "Got service object: " << cliService->metaObject()->className();
+    else qDebug() << "Got null service";
+  }
+  catch (const ctkServiceException& e)
+  {
+    qDebug() << e;
+  }
 }
 
 void ctkPluginBrowser::qtResourceDoubleClicked(const QModelIndex& index)

+ 1 - 1
Libs/PluginFramework/ctkPlugin.cpp

@@ -111,7 +111,7 @@
 
   void ctkPlugin::stop(const StopOptions& options)
   {
-    Q_UNUSED(options)
+    //TODO Plugin::stop()
   }
 
   ctkPluginContext* ctkPlugin::getPluginContext() const

+ 4 - 9
Libs/PluginFramework/ctkPluginContext.cpp

@@ -103,30 +103,25 @@
     return d->plugin->fwCtx->services.registerService(d->plugin, clazzes, service, properties);
   }
 
-  QList<ctkServiceReference*> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
+  QList<ctkServiceReference> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
   {
     Q_D(ctkPluginContext);
     d->isPluginContextValid();
     return d->plugin->fwCtx->services.get(clazz, filter);
   }
 
-  ctkServiceReference* ctkPluginContext::getServiceReference(const QString& clazz)
+  ctkServiceReference ctkPluginContext::getServiceReference(const QString& clazz)
   {
     Q_D(ctkPluginContext);
     d->isPluginContextValid();
     return d->plugin->fwCtx->services.get(d->plugin, clazz);
   }
 
-  QObject* ctkPluginContext::getService(ctkServiceReference* reference)
+  QObject* ctkPluginContext::getService(ctkServiceReference reference)
   {
-    if (reference == 0)
-    {
-      throw std::invalid_argument("Null ctkServiceReference is not valid");
-    }
-
     Q_D(ctkPluginContext);
     d->isPluginContextValid();
-    return reference->d_func()->getService(d->plugin->q_func());
+    return reference.d_func()->getService(d->plugin->q_func());
   }
 
   bool ctkPluginContext::connectPluginListener(const QObject* receiver, const char* method,

+ 4 - 3
Libs/PluginFramework/ctkPluginContext.h

@@ -245,7 +245,7 @@
      *         contains an invalid filter expression that cannot be parsed.
      * @throws std::logic_error If this ctkPluginContext is no longer valid.
      */
-    QList<ctkServiceReference*> getServiceReferences(const QString& clazz, const QString& filter = QString());
+    QList<ctkServiceReference> getServiceReferences(const QString& clazz, const QString& filter = QString());
 
     /**
      * Returns a <code>ctkServiceReference</code> object for a service that
@@ -274,9 +274,10 @@
      * @return A <code>ctkServiceReference</code> object, or <code>0</code> if
      *         no services are registered which implement the named class.
      * @throws std::logic_error If this ctkPluginContext is no longer valid.
+     * @throws ctkServiceException It no service was registered under the given class name.
      * @see #getServiceReferences(const QString&, const QString&)
      */
-    ctkServiceReference* getServiceReference(const QString& clazz);
+    ctkServiceReference getServiceReference(const QString& clazz);
 
     /**
      * Returns the service object referenced by the specified
@@ -335,7 +336,7 @@
      * @see #ungetService(ctkServiceReference*)
      * @see ctkServiceFactory
      */
-    QObject* getService(ctkServiceReference* reference);
+    QObject* getService(ctkServiceReference reference);
 
     ctkPlugin* installPlugin(const QUrl& location, QIODevice* in = 0);
 

+ 74 - 64
Libs/PluginFramework/ctkServiceReference.cpp

@@ -28,88 +28,98 @@
 #include <QStringList>
 #include <QMutexLocker>
 
+ctkServiceReference::ctkServiceReference(const ctkServiceReference& ref)
+  : d_ptr(ref.d_ptr)
+{
+  d_func()->ref.ref();
+}
 
-  ctkServiceReference::ctkServiceReference(ctkServiceRegistrationPrivate* reg)
-    : d_ptr(new ctkServiceReferencePrivate(reg))
-  {
+ctkServiceReference::ctkServiceReference(ctkServiceRegistrationPrivate* reg)
+  : d_ptr(new ctkServiceReferencePrivate(reg))
+{
 
-  }
+}
 
-  ctkServiceReference::~ctkServiceReference()
-  {
+ctkServiceReference::~ctkServiceReference()
+{
+  if (!d_func()->ref.deref())
     delete d_ptr;
-  }
+}
 
-  QVariant ctkServiceReference::getProperty(const QString& key) const
-  {
-    Q_D(const ctkServiceReference);
+QVariant ctkServiceReference::getProperty(const QString& key) const
+{
+  Q_D(const ctkServiceReference);
 
-    QMutexLocker lock(&d->registration->propsLock);
+  QMutexLocker lock(&d->registration->propsLock);
 
-    return d->registration->properties.value(key);
-  }
+  return d->registration->properties.value(key);
+}
 
-  QStringList ctkServiceReference::getPropertyKeys() const
-  {
-    Q_D(const ctkServiceReference);
+QStringList ctkServiceReference::getPropertyKeys() const
+{
+  Q_D(const ctkServiceReference);
 
-    QMutexLocker lock(&d->registration->propsLock);
+  QMutexLocker lock(&d->registration->propsLock);
 
-    return d->registration->properties.keys();
-  }
+  return d->registration->properties.keys();
+}
 
-  ctkPlugin* ctkServiceReference::getPlugin() const
+ctkPlugin* ctkServiceReference::getPlugin() const
+{
+  return d_func()->registration->plugin->q_func();
+}
+
+QList<ctkPlugin*> ctkServiceReference::getUsingPlugins() const
+{
+  Q_D(const ctkServiceReference);
+
+  QMutexLocker lock(&d->registration->propsLock);
+
+  return d->registration->dependents.keys();
+}
+
+bool ctkServiceReference::operator<(const ctkServiceReference& reference) const
+{
+  bool sameFw = d_func()->registration->plugin->fwCtx == reference.d_func()->registration->plugin->fwCtx;
+  if (!sameFw)
   {
-    return d_func()->registration->plugin->q_func();
+    throw std::invalid_argument("Can not compare service references "
+                                "belonging to different framework "
+                                "instances.");
   }
 
-  QList<ctkPlugin*> ctkServiceReference::getUsingPlugins() const
+  int r1 = getProperty(PluginConstants::SERVICE_RANKING).toInt();
+  int r2 = reference.getProperty(PluginConstants::SERVICE_RANKING).toInt();
+
+  if (r1 != r2)
   {
-    Q_D(const ctkServiceReference);
-
-    QMutexLocker lock(&d->registration->propsLock);
-
-    if (d->registration->reference != 0)
-    {
-      return d->registration->dependents.keys();
-    }
-    else
-    {
-      return QList<ctkPlugin*>();
-    }
+    // use ranking if ranking differs
+    return r1 < r2 ? false : true;
   }
-
-  bool ctkServiceReference::operator<(const ctkServiceReference& reference) const
+  else
   {
-    bool sameFw = d_func()->registration->plugin->fwCtx == reference.d_func()->registration->plugin->fwCtx;
-    if (!sameFw)
-    {
-      throw std::invalid_argument("Can not compare service references "
-                                  "belonging to different framework "
-                                  "instances.");
-    }
-
-    int r1 = getProperty(PluginConstants::SERVICE_RANKING).toInt();
-    int r2 = reference.getProperty(PluginConstants::SERVICE_RANKING).toInt();
-
-    if (r1 != r2)
-    {
-      // use ranking if ranking differs
-      return r1 < r2 ? false : true;
-    }
-    else
-    {
-      qlonglong id1 = getProperty(PluginConstants::SERVICE_ID).toLongLong();
-      qlonglong id2 = reference.getProperty(PluginConstants::SERVICE_ID).toLongLong();
-
-      // otherwise compare using IDs,
-      // is less than if it has a higher ID.
-      return id2< id1;
-    }
+    qlonglong id1 = getProperty(PluginConstants::SERVICE_ID).toLongLong();
+    qlonglong id2 = reference.getProperty(PluginConstants::SERVICE_ID).toLongLong();
+
+    // otherwise compare using IDs,
+    // is less than if it has a higher ID.
+    return id2< id1;
   }
+}
 
-  bool ctkServiceReference::operator==(const ctkServiceReference& reference) const
-  {
-    return d_func()->registration == reference.d_func()->registration;
+bool ctkServiceReference::operator==(const ctkServiceReference& reference) const
+{
+  return d_func()->registration == reference.d_func()->registration;
+}
+
+ctkServiceReference& ctkServiceReference::operator=(const ctkServiceReference& reference)
+{
+  ctkServiceReferencePrivate* curr_d = d_func();
+  d_ptr = reference.d_ptr;
+  d_ptr->ref.ref();
+
+  if (!curr_d->ref.deref())
+    delete curr_d;
 
+  return *this;
 }

+ 5 - 1
Libs/PluginFramework/ctkServiceReference.h

@@ -67,6 +67,8 @@
 
   public:
 
+    ctkServiceReference(const ctkServiceReference& ref);
+
     ~ctkServiceReference();
 
     /**
@@ -166,6 +168,8 @@
 
     bool operator==(const ctkServiceReference& reference) const;
 
+    ctkServiceReference& operator=(const ctkServiceReference& reference);
+
 
   protected:
 
@@ -174,7 +178,7 @@
 
     ctkServiceReference(ctkServiceRegistrationPrivate* reg);
 
-    ctkServiceReferencePrivate * const d_ptr;
+    ctkServiceReferencePrivate * d_ptr;
 
   };
 

+ 30 - 33
Libs/PluginFramework/ctkServiceReferencePrivate.cpp

@@ -33,7 +33,7 @@
 
 
   ctkServiceReferencePrivate::ctkServiceReferencePrivate(ctkServiceRegistrationPrivate* reg)
-    : registration(reg)
+    : ref(1), registration(reg)
   {
   }
 
@@ -122,50 +122,47 @@
   {
     QMutexLocker lock(&registration->propsLock);
     bool hadReferences = false;
-    if (registration->reference != 0)
-    {
-      bool removeService = false;
+    bool removeService = false;
 
-      int count= registration->dependents.value(plugin);
-      if (count > 0)
-      {
-        hadReferences = true;
-      }
+    int count= registration->dependents.value(plugin);
+    if (count > 0)
+    {
+      hadReferences = true;
+    }
 
-      if(checkRefCounter)
+    if(checkRefCounter)
+    {
+      if (count > 1)
       {
-        if (count > 1)
-        {
-            registration->dependents[plugin] = count - 1;
-        }
-        else if(count == 1)
-        {
-          removeService = true;
-        }
+          registration->dependents[plugin] = count - 1;
       }
-      else
+      else if(count == 1)
       {
         removeService = true;
       }
+    }
+    else
+    {
+      removeService = true;
+    }
 
-      if (removeService)
+    if (removeService)
+    {
+      QObject* sfi = registration->serviceInstances[plugin];
+      registration->serviceInstances.remove(plugin);
+      if (sfi != 0)
       {
-        QObject* sfi = registration->serviceInstances[plugin];
-        registration->serviceInstances.remove(plugin);
-        if (sfi != 0)
+        try
         {
-          try
-          {
-            qobject_cast<ctkServiceFactory*>(registration->getService())->ungetService(plugin,
-                registration->q_func(), sfi);
-          }
-          catch (const std::exception& e)
-          {
-            plugin->d_func()->fwCtx->listeners.frameworkError(registration->plugin->q_func(), e);
-          }
+          qobject_cast<ctkServiceFactory*>(registration->getService())->ungetService(plugin,
+              registration->q_func(), sfi);
+        }
+        catch (const std::exception& e)
+        {
+          plugin->d_func()->fwCtx->listeners.frameworkError(registration->plugin->q_func(), e);
         }
-        registration->dependents.remove(plugin);
       }
+      registration->dependents.remove(plugin);
     }
 
     return hadReferences;

+ 43 - 35
Libs/PluginFramework/ctkServiceReferencePrivate.h

@@ -23,42 +23,50 @@
 #ifndef CTKSERVICEREFERENCEPRIVATE_H
 #define CTKSERVICEREFERENCEPRIVATE_H
 
-class QObject;
+#include <QAtomicInt>
 
+class QObject;
 
-  class ctkServiceRegistrationPrivate;
-  class ctkPlugin;
-
-  class ctkServiceReferencePrivate
-  {
-  public:
-
-    ctkServiceReferencePrivate(ctkServiceRegistrationPrivate* reg);
-
-    /**
-      * Get the service object.
-      *
-      * @param plugin requester of service.
-      * @return Service requested or null in case of failure.
-      */
-    QObject* getService(ctkPlugin* plugin);
-
-    /**
-     * Unget the service object.
-     *
-     * @param plugin Plugin who wants remove service.
-     * @param checkRefCounter If true decrement refence counter and remove service
-     *                        if we reach zero. If false remove service without
-     *                        checking refence counter.
-     * @return True if service was remove or false if only refence counter was
-     *         decremented.
-     */
-    bool ungetService(ctkPlugin* plugin, bool checkRefCounter);
-
-    /**
-     * Link to registration object for this reference.
-     */
-    ctkServiceRegistrationPrivate* registration;
-  };
+class ctkServiceRegistrationPrivate;
+class ctkPlugin;
+
+class ctkServiceReferencePrivate
+{
+public:
+
+  ctkServiceReferencePrivate(ctkServiceRegistrationPrivate* reg);
+
+  virtual ~ctkServiceReferencePrivate() {}
+
+  /**
+    * Get the service object.
+    *
+    * @param plugin requester of service.
+    * @return Service requested or null in case of failure.
+    */
+  QObject* getService(ctkPlugin* plugin);
+
+  /**
+   * Unget the service object.
+   *
+   * @param plugin Plugin who wants remove service.
+   * @param checkRefCounter If true decrement refence counter and remove service
+   *                        if we reach zero. If false remove service without
+   *                        checking refence counter.
+   * @return True if service was remove or false if only refence counter was
+   *         decremented.
+   */
+  bool ungetService(ctkPlugin* plugin, bool checkRefCounter);
+
+  /**
+   * Reference count for implicitly shared private implementation.
+   */
+  QAtomicInt ref;
+
+  /**
+   * Link to registration object for this reference.
+   */
+  ctkServiceRegistrationPrivate* registration;
+};
 
 #endif // CTKSERVICEREFERENCEPRIVATE_H

+ 67 - 68
Libs/PluginFramework/ctkServiceRegistration.cpp

@@ -30,31 +30,31 @@
 #include <stdexcept>
 
 
-  ctkServiceRegistration::ctkServiceRegistration(ctkPluginPrivate* plugin, QObject* service,
-                      const ServiceProperties& props)
-    : d_ptr(new ctkServiceRegistrationPrivate(this, plugin, service, props))
-  {
+ctkServiceRegistration::ctkServiceRegistration(ctkPluginPrivate* plugin, QObject* service,
+                    const ServiceProperties& props)
+  : d_ptr(new ctkServiceRegistrationPrivate(this, plugin, service, props))
+{
 
-  }
+}
 
-  ctkServiceRegistration::ctkServiceRegistration(ctkServiceRegistrationPrivate& dd)
-    : d_ptr(&dd)
-  {
+ctkServiceRegistration::ctkServiceRegistration(ctkServiceRegistrationPrivate& dd)
+  : d_ptr(&dd)
+{
 
-  }
+}
 
-  ctkServiceReference* ctkServiceRegistration::getReference()
-  {
-    Q_D(ctkServiceRegistration);
+ctkServiceReference ctkServiceRegistration::getReference() const
+{
+  Q_D(const ctkServiceRegistration);
 
-    if (!d->available) throw std::logic_error("Service is unregistered");
+  if (!d->available) throw std::logic_error("Service is unregistered");
 
-    return d->reference;
-  }
+  return d->reference;
+}
 
-  void ctkServiceRegistration::setProperties(const ServiceProperties& properties)
-  {
-    Q_UNUSED(properties)
+void ctkServiceRegistration::setProperties(const ServiceProperties& properties)
+{
+  Q_UNUSED(properties)
 //    QMutexLocker lock(eventLock);
 //          Set before;
 //          // TBD, optimize the locking of services
@@ -87,77 +87,76 @@
 //                            new ServiceEvent(ServiceEvent.MODIFIED_ENDMATCH, reference),
 //                            null);
 
-  }
+}
 
-  void ctkServiceRegistration::unregister()
+void ctkServiceRegistration::unregister()
+{
+  Q_D(ctkServiceRegistration);
+
+  if (d->unregistering) return; // Silently ignore redundant unregistration.
   {
-    Q_D(ctkServiceRegistration);
+    QMutexLocker lock(&d->eventLock);
+    if (d->unregistering) return;
+    d->unregistering = true;
 
-    if (d->unregistering) return; // Silently ignore redundant unregistration.
+    if (d->available)
     {
-      QMutexLocker lock(&d->eventLock);
-      if (d->unregistering) return;
-      d->unregistering = true;
-
-      if (d->available)
+      if (d->plugin)
       {
-        if (d->plugin)
-        {
-          d->plugin->fwCtx->services.removeServiceRegistration(this);
-        }
-      }
-      else
-      {
-        throw std::logic_error("Service is unregistered");
+        d->plugin->fwCtx->services.removeServiceRegistration(this);
       }
     }
-
-    if (d->plugin)
+    else
     {
-      //TODO
+      throw std::logic_error("Service is unregistered");
+    }
+  }
+
+  if (d->plugin)
+  {
+    //TODO
 //      bundle.fwCtx.listeners
 //            .serviceChanged(bundle.fwCtx.listeners.getMatchingServiceListeners(reference),
 //                            new ServiceEvent(ServiceEvent.UNREGISTERING, reference),
 //                            null);
-    }
+  }
 
+  {
+    QMutexLocker lock(&d->eventLock);
     {
-      QMutexLocker lock(&d->eventLock);
+      QMutexLocker lock2(&d->propsLock);
+      d->available = false;
+      if (d->plugin)
       {
-        QMutexLocker lock2(&d->propsLock);
-        d->available = false;
-        if (d->plugin)
+        for (QHashIterator<ctkPlugin*, QObject*> i(d->serviceInstances); i.hasNext();)
         {
-          for (QHashIterator<ctkPlugin*, QObject*> i(d->serviceInstances); i.hasNext();)
+          QObject* obj = i.next().value();
+          try
+          {
+            // NYI, don't call inside lock
+            qobject_cast<ctkServiceFactory*>(d->service)->ungetService(i.key(),
+                                                       this,
+                                                       obj);
+          }
+          catch (const std::exception& ue)
           {
-            QObject* obj = i.next().value();
-            try
-            {
-              // NYI, don't call inside lock
-              qobject_cast<ctkServiceFactory*>(d->service)->ungetService(i.key(),
-                                                         this,
-                                                         obj);
-            }
-            catch (const std::exception& ue)
-            {
-              ctkPluginFrameworkEvent pfwEvent(ctkPluginFrameworkEvent::ERROR, d->plugin->q_func(), ue);
-              d->plugin->fwCtx->listeners
-                  .emitFrameworkEvent(pfwEvent);
-            }
+            ctkPluginFrameworkEvent pfwEvent(ctkPluginFrameworkEvent::ERROR, d->plugin->q_func(), ue);
+            d->plugin->fwCtx->listeners
+                .emitFrameworkEvent(pfwEvent);
           }
         }
-        d->plugin = 0;
-        d->dependents.clear();
-        d->service = 0;
-        d->serviceInstances.clear();;
-        d->unregistering = false;
       }
+      d->plugin = 0;
+      d->dependents.clear();
+      d->service = 0;
+      d->serviceInstances.clear();;
+      d->unregistering = false;
     }
   }
+}
 
-  bool ctkServiceRegistration::operator<(const ctkServiceRegistration& o) const
-  {
-    Q_D(const ctkServiceRegistration);
-    return d->reference->operator <(*(o.d_func()->reference));
-
+bool ctkServiceRegistration::operator<(const ctkServiceRegistration& o) const
+{
+  Q_D(const ctkServiceRegistration);
+  return d->reference <(o.d_func()->reference);
 }

+ 1 - 1
Libs/PluginFramework/ctkServiceRegistration.h

@@ -64,7 +64,7 @@
      *         unregistered.
      * @return <code>ctkServiceReference</code> object.
      */
-    ctkServiceReference* getReference();
+    ctkServiceReference getReference() const;
 
     /**
      * Updates the properties associated with a service.

+ 24 - 26
Libs/PluginFramework/ctkServiceRegistrationPrivate.cpp

@@ -22,29 +22,27 @@
 #include "ctkServiceRegistrationPrivate.h"
 
 
-  ctkServiceRegistrationPrivate::ctkServiceRegistrationPrivate(ctkServiceRegistration* sr,
-                                                         ctkPluginPrivate* plugin, QObject* service,
-                                                         const ServiceProperties& props)
-                               : q_ptr(sr), service(service), plugin(plugin), reference(new ctkServiceReference(this)),
-                               properties(props), available(true), unregistering(false)
-  {
-
-  }
-
-  ctkServiceRegistrationPrivate::~ctkServiceRegistrationPrivate()
-  {
-    delete reference;
-  }
-
-  bool ctkServiceRegistrationPrivate::isUsedByPlugin(ctkPlugin* p)
-  {
-    QHash<ctkPlugin*, int> deps = dependents;
-    return deps.contains(p);
-  }
-
-  QObject* ctkServiceRegistrationPrivate::getService()
-  {
-    return service;
-  }
-
-
+ctkServiceRegistrationPrivate::ctkServiceRegistrationPrivate(ctkServiceRegistration* sr,
+                                                       ctkPluginPrivate* plugin, QObject* service,
+                                                       const ServiceProperties& props)
+                             : q_ptr(sr), service(service), plugin(plugin), reference(this),
+                             properties(props), available(true), unregistering(false)
+{
+
+}
+
+ctkServiceRegistrationPrivate::~ctkServiceRegistrationPrivate()
+{
+
+}
+
+bool ctkServiceRegistrationPrivate::isUsedByPlugin(ctkPlugin* p)
+{
+  QHash<ctkPlugin*, int> deps = dependents;
+  return deps.contains(p);
+}
+
+QObject* ctkServiceRegistrationPrivate::getService()
+{
+  return service;
+}

+ 1 - 1
Libs/PluginFramework/ctkServiceRegistrationPrivate.h

@@ -57,7 +57,7 @@
     /**
      * Reference object to this service registration.
      */
-    ctkServiceReference* reference;
+    ctkServiceReference reference;
 
     /**
      * Service properties.

+ 10 - 9
Libs/PluginFramework/ctkServices.cpp

@@ -29,6 +29,7 @@
 
 #include "ctkServiceFactory.h"
 #include "ctkPluginConstants.h"
+#include "ctkServiceException.h"
 #include "ctkServiceRegistrationPrivate.h"
 #include "ctkQtServiceRegistration_p.h"
 #include "ctkLDAPExpr.h"
@@ -146,7 +147,7 @@ ctkServiceRegistration* ctkServices::registerService(ctkPluginPrivate* plugin,
     }
   }
 
-  //ctkServiceReference* r = res->getReference();
+  //ctkServiceReference r = res->getReference();
   // TODO
   //Listeners l = bundle.fwCtx.listeners;
   //l.serviceChanged(l.getMatchingServiceListeners(r),
@@ -289,13 +290,13 @@ QList<ctkServiceRegistration*> ctkServices::get(const QString& clazz) const
 }
 
 
-ctkServiceReference* ctkServices::get(ctkPluginPrivate* plugin, const QString& clazz) const
+ctkServiceReference ctkServices::get(ctkPluginPrivate* plugin, const QString& clazz) const
 {
   QMutexLocker lock(&mutex);
   try {
-    QList<ctkServiceReference*> srs = get(clazz, QString());
+    QList<ctkServiceReference> srs = get(clazz, QString());
     qDebug() << "get service ref" << clazz << "for plugin"
-             << plugin->location << " = " << srs;
+             << plugin->location << " = " << srs.size() << "refs";
 
     if (!srs.isEmpty()) {
       return srs.front();
@@ -304,11 +305,11 @@ ctkServiceReference* ctkServices::get(ctkPluginPrivate* plugin, const QString& c
   catch (const std::invalid_argument& )
   { }
 
-  return 0;
+  throw ctkServiceException(QString("No service registered for: ") + clazz);
 }
 
 
-QList<ctkServiceReference*> ctkServices::get(const QString& clazz, const QString& filter) const
+QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString& filter) const
 {
   QMutexLocker lock(&mutex);
 
@@ -364,7 +365,7 @@ QList<ctkServiceReference*> ctkServices::get(const QString& clazz, const QString
     }
     else
     {
-      return QList<ctkServiceReference*>();
+      return QList<ctkServiceReference>();
     }
     if (!filter.isEmpty())
     {
@@ -372,11 +373,11 @@ QList<ctkServiceReference*> ctkServices::get(const QString& clazz, const QString
     }
   }
 
-  QList<ctkServiceReference*> res;
+  QList<ctkServiceReference> res;
   while (s->hasNext())
   {
     ctkServiceRegistration* sr = s->next();
-    ctkServiceReference* sri = sr->getReference();
+    ctkServiceReference sri = sr->getReference();
 
     if (filter.isEmpty() || ldap->evaluate(sr->d_func()->properties, false))
     {

+ 4 - 2
Libs/PluginFramework/ctkServices_p.h

@@ -141,8 +141,10 @@ public:
    * @param plugin The plugin requesting reference
    * @param clazz The class name of the requested service.
    * @return A {@link ctkServiceReference} object.
+   * @throws ctkServiceException if no service was registered under the given
+   *         clazz name.
    */
-  ctkServiceReference* get(ctkPluginPrivate* plugin, const QString& clazz) const;
+  ctkServiceReference get(ctkPluginPrivate* plugin, const QString& clazz) const;
 
 
   /**
@@ -154,7 +156,7 @@ public:
    * @param plugin The plugin requesting reference.
    * @return A list of {@link ctkServiceReference} object.
    */
-  QList<ctkServiceReference*> get(const QString& clazz, const QString& filter) const;
+  QList<ctkServiceReference> get(const QString& clazz, const QString& filter) const;
 
 
   /**