Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java32
1 files changed, 23 insertions, 9 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java
index 661021b5a..52d935d01 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/PrototypeServiceFactoryUse.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,7 +11,9 @@
package org.eclipse.osgi.internal.serviceregistry;
-import java.util.*;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.BundleContextImpl;
import org.eclipse.osgi.internal.messages.Msg;
@@ -27,9 +29,9 @@ import org.osgi.framework.*;
* @ThreadSafe
*/
public class PrototypeServiceFactoryUse<S> extends ServiceFactoryUse<S> {
- /** Service objects returned by PrototypeServiceFactory.getService() */
+ /** Service objects returned by PrototypeServiceFactory.getService() and their use count. */
/* @GuardedBy("this") */
- private final Set<S> serviceObjects;
+ private final Map<S, AtomicInteger> serviceObjects;
/**
* Constructs a service use encapsulating the service object.
@@ -39,7 +41,7 @@ public class PrototypeServiceFactoryUse<S> extends ServiceFactoryUse<S> {
*/
PrototypeServiceFactoryUse(BundleContextImpl context, ServiceRegistrationImpl<S> registration) {
super(context, registration);
- this.serviceObjects = Collections.newSetFromMap(new IdentityHashMap<S, Boolean>());
+ this.serviceObjects = new IdentityHashMap<S, AtomicInteger>();
}
/**
@@ -60,7 +62,15 @@ public class PrototypeServiceFactoryUse<S> extends ServiceFactoryUse<S> {
if (service == null) {
return null;
}
- serviceObjects.add(service);
+ AtomicInteger useCount = serviceObjects.get(service);
+ if (useCount == null) {
+ serviceObjects.put(service, new AtomicInteger(1));
+ } else {
+ if (useCount.getAndIncrement() == Integer.MAX_VALUE) {
+ useCount.getAndDecrement();
+ throw new ServiceException(Msg.SERVICE_USE_OVERFLOW);
+ }
+ }
return service;
}
@@ -76,13 +86,17 @@ public class PrototypeServiceFactoryUse<S> extends ServiceFactoryUse<S> {
@Override
boolean releaseServiceObject(final S service) {
assert Thread.holdsLock(this);
- if ((service == null) || !serviceObjects.remove(service)) {
+ if ((service == null) || !serviceObjects.containsKey(service)) {
throw new IllegalArgumentException(Msg.SERVICE_OBJECTS_UNGET_ARGUMENT_EXCEPTION);
}
if (debug.DEBUG_SERVICES) {
Debug.println("ungetService[factory=" + registration.getBundle() + "](" + context.getBundleImpl() + "," + registration + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
- factoryUngetService(service);
+ AtomicInteger useCount = serviceObjects.get(service);
+ if (useCount.decrementAndGet() < 1) {
+ serviceObjects.remove(service);
+ factoryUngetService(service);
+ }
return true;
}
@@ -99,7 +113,7 @@ public class PrototypeServiceFactoryUse<S> extends ServiceFactoryUse<S> {
@Override
void release() {
super.release();
- for (S service : serviceObjects) {
+ for (S service : serviceObjects.keySet()) {
if (debug.DEBUG_SERVICES) {
Debug.println("releaseService[factory=" + registration.getBundle() + "](" + context.getBundleImpl() + "," + registration + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}

Back to the top