Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlyn Normington2012-08-30 15:43:32 +0000
committerGlyn Normington2012-08-30 15:43:32 +0000
commit708b8669657659cc392e098dce046300a2cad747 (patch)
tree3609686f6b6ea88c345d68b2c5d1387892215d1a /extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java
parentb545a6b9cd440d0da5d8a11e7c04adf672867b02 (diff)
downloadorg.eclipse.gemini.blueprint-708b8669657659cc392e098dce046300a2cad747.tar.gz
org.eclipse.gemini.blueprint-708b8669657659cc392e098dce046300a2cad747.tar.xz
org.eclipse.gemini.blueprint-708b8669657659cc392e098dce046300a2cad747.zip
384748: thread safety improvements
Diffstat (limited to 'extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java')
-rw-r--r--extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java148
1 files changed, 102 insertions, 46 deletions
diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java
index 8d303fa..676ecda 100644
--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java
+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/dependencies/startup/DependencyServiceManager.java
@@ -22,6 +22,8 @@ import java.security.PrivilegedExceptionAction;
22import java.util.ArrayList; 22import java.util.ArrayList;
23import java.util.Collection; 23import java.util.Collection;
24import java.util.Collections; 24import java.util.Collections;
25import java.util.HashMap;
26import java.util.HashSet;
25import java.util.Iterator; 27import java.util.Iterator;
26import java.util.LinkedHashMap; 28import java.util.LinkedHashMap;
27import java.util.List; 29import java.util.List;
@@ -63,13 +65,15 @@ import org.eclipse.gemini.blueprint.util.OsgiStringUtils;
63 */ 65 */
64public class DependencyServiceManager { 66public class DependencyServiceManager {
65 67
66 private static final Log log = LogFactory.getLog(DependencyServiceManager.class); 68 private static final Map<MandatoryServiceDependency, String> UNMODIFIABLE_DEPENDENCY_MAP = Collections.unmodifiableMap(new HashMap<MandatoryServiceDependency, String>(0));
69
70 private static final Log log = LogFactory.getLog(DependencyServiceManager.class);
71
72 private final Object monitor = new Object();
67 73
68 protected final Map<MandatoryServiceDependency, String> dependencies = 74 protected final Map<MandatoryServiceDependency, String> dependencies = new LinkedHashMap<MandatoryServiceDependency, String>();
69 Collections.synchronizedMap(new LinkedHashMap<MandatoryServiceDependency, String>());
70 75
71 protected final Map<MandatoryServiceDependency, String> unsatisfiedDependencies = 76 protected final Map<MandatoryServiceDependency, String> unsatisfiedDependencies = new LinkedHashMap<MandatoryServiceDependency, String>();
72 Collections.synchronizedMap(new LinkedHashMap<MandatoryServiceDependency, String>());
73 77
74 private final ContextExecutorAccessor contextStateAccessor; 78 private final ContextExecutorAccessor contextStateAccessor;
75 79
@@ -108,7 +112,7 @@ public class DependencyServiceManager {
108 boolean trace = log.isTraceEnabled(); 112 boolean trace = log.isTraceEnabled();
109 113
110 try { 114 try {
111 if (unsatisfiedDependencies.isEmpty()) { 115 if (isSatisfied()) {
112 116
113 // already completed but likely called due to threading 117 // already completed but likely called due to threading
114 if (trace) { 118 if (trace) {
@@ -136,7 +140,7 @@ public class DependencyServiceManager {
136 } 140 }
137 141
138 // Good to go! 142 // Good to go!
139 if (unsatisfiedDependencies.isEmpty()) { 143 if (isSatisfied()) {
140 deregister(); 144 deregister();
141 // context.listener = null; 145 // context.listener = null;
142 log.info("No unsatisfied OSGi service dependencies; completing initialization for " 146 log.info("No unsatisfied OSGi service dependencies; completing initialization for "
@@ -153,9 +157,9 @@ public class DependencyServiceManager {
153 log.error("Exception during dependency processing for " + context.getDisplayName(), th); 157 log.error("Exception during dependency processing for " + context.getDisplayName(), th);
154 contextStateAccessor.fail(th); 158 contextStateAccessor.fail(th);
155 } 159 }
156 } 160 }
157 161
158 private void updateDependencies(ServiceEvent serviceEvent) { 162 private void updateDependencies(ServiceEvent serviceEvent) {
159 boolean trace = log.isTraceEnabled(); 163 boolean trace = log.isTraceEnabled();
160 boolean debug = log.isDebugEnabled(); 164 boolean debug = log.isDebugEnabled();
161 165
@@ -167,7 +171,12 @@ public class DependencyServiceManager {
167 contextToString = context.getDisplayName(); 171 contextToString = context.getDisplayName();
168 } 172 }
169 173
170 for (MandatoryServiceDependency dependency : dependencies.keySet()) { 174 Set<MandatoryServiceDependency> mandatoryServiceDependencies;
175 synchronized (monitor) {
176 mandatoryServiceDependencies = new HashSet<MandatoryServiceDependency>(dependencies.keySet());
177 }
178
179 for (MandatoryServiceDependency dependency : mandatoryServiceDependencies) {
171 // check all dependencies (there might be multiple imports for the same service) 180 // check all dependencies (there might be multiple imports for the same service)
172 if (dependency.matches(serviceEvent)) { 181 if (dependency.matches(serviceEvent)) {
173 if (trace) { 182 if (trace) {
@@ -179,18 +188,24 @@ public class DependencyServiceManager {
179 case ServiceEvent.REGISTERED: 188 case ServiceEvent.REGISTERED:
180 case ServiceEvent.MODIFIED: 189 case ServiceEvent.MODIFIED:
181 dependency.increment(); 190 dependency.increment();
182 if (unsatisfiedDependencies.remove(dependency) != null) { 191 String removedDependency;
183 if (debug) { 192 synchronized (monitor) {
184 log.debug("Registered dependency for " + contextToString + "; eliminating " 193 removedDependency = unsatisfiedDependencies.remove(dependency);
185 + dependency + ", remaining [" + unsatisfiedDependencies + "]"); 194 }
186 } 195 if (removedDependency != null) {
187 196 Map<MandatoryServiceDependency, String> unsatisfiedDependenciesSnapshot = getUnsatisfiedDependencies();
188 sendDependencySatisfiedEvent(dependency); 197 if (debug) {
189 sendBootstrappingDependenciesEvent(unsatisfiedDependencies.keySet()); 198 log.debug("Registered dependency for " + contextToString + "; eliminating "
199 + dependency + ", remaining [" + unsatisfiedDependenciesSnapshot + "]");
200 }
201
202 sendDependencySatisfiedEvent(dependency);
203 sendBootstrappingDependenciesEvent(unsatisfiedDependenciesSnapshot.keySet());
190 } else { 204 } else {
191 if (debug) { 205 if (debug) {
206 Map<MandatoryServiceDependency, String> unsatisfiedDependenciesSnapshot = getUnsatisfiedDependencies();
192 log.debug("Increasing the number of matching services for " + contextToString + "; " 207 log.debug("Increasing the number of matching services for " + contextToString + "; "
193 + dependency + ", remaining [" + unsatisfiedDependencies + "]"); 208 + dependency + ", remaining [" + unsatisfiedDependenciesSnapshot + "]");
194 } 209 }
195 } 210 }
196 211
@@ -199,14 +214,17 @@ public class DependencyServiceManager {
199 case ServiceEvent.UNREGISTERING: 214 case ServiceEvent.UNREGISTERING:
200 int count = dependency.decrement(); 215 int count = dependency.decrement();
201 if (count == 0) { 216 if (count == 0) {
202 unsatisfiedDependencies.put(dependency, dependency.getBeanName()); 217 synchronized (monitor) {
203 if (debug) { 218 unsatisfiedDependencies.put(dependency, dependency.getBeanName());
219 }
220 Map<MandatoryServiceDependency, String> unsatisfiedDependenciesSnapshot = getUnsatisfiedDependencies();
221 if (debug) {
204 log.debug("Unregistered dependency for " + contextToString + " adding " + dependency 222 log.debug("Unregistered dependency for " + contextToString + " adding " + dependency
205 + "; total unsatisfied [" + unsatisfiedDependencies + "]"); 223 + "; total unsatisfied [" + unsatisfiedDependenciesSnapshot + "]");
206 } 224 }
207 225
208 sendDependencyUnsatisfiedEvent(dependency); 226 sendDependencyUnsatisfiedEvent(dependency);
209 sendBootstrappingDependenciesEvent(unsatisfiedDependencies.keySet()); 227 sendBootstrappingDependenciesEvent(unsatisfiedDependenciesSnapshot.keySet());
210 } else { 228 } else {
211 if (debug) { 229 if (debug) {
212 log.debug("Decreasing the number of matching services for " + contextToString + "; " 230 log.debug("Decreasing the number of matching services for " + contextToString + "; "
@@ -226,7 +244,8 @@ public class DependencyServiceManager {
226 } 244 }
227 } 245 }
228 } 246 }
229 } 247 }
248
230 } 249 }
231 250
232 /** 251 /**
@@ -280,19 +299,31 @@ public class DependencyServiceManager {
280 throw (Error) th; 299 throw (Error) th;
281 } 300 }
282 301
283 if (log.isDebugEnabled()) { 302 Collection<String> unsatisfiedDependencyValues = getUnsatisfiedDependencies().values();
284 log.debug(dependencies.size() + " OSGi service dependencies, " + unsatisfiedDependencies.size() 303
285 + " unsatisfied (for beans " + unsatisfiedDependencies.values() + ") in " 304 if (log.isDebugEnabled()) {
305 int numDependencies;
306 int numUnsatisfiedDependencies;
307 synchronized (monitor) {
308 numDependencies = dependencies.size();
309 numUnsatisfiedDependencies = unsatisfiedDependencies.size();
310 }
311 log.debug(numDependencies + " OSGi service dependencies, " + numUnsatisfiedDependencies
312 + " unsatisfied (for beans " + unsatisfiedDependencyValues + ") in "
286 + context.getDisplayName()); 313 + context.getDisplayName());
287 } 314 }
288 315
289 if (!unsatisfiedDependencies.isEmpty()) { 316 if (!isSatisfied()) {
290 log.info(context.getDisplayName() + " is waiting for unsatisfied dependencies [" 317 log.info(context.getDisplayName() + " is waiting for unsatisfied dependencies ["
291 + unsatisfiedDependencies.values() + "]"); 318 + unsatisfiedDependencyValues + "]");
292 } 319 }
293 if (log.isTraceEnabled()) { 320 if (log.isTraceEnabled()) {
294 log.trace("Total OSGi service dependencies beans " + dependencies.values()); 321 Collection<String> dependencyValues;
295 log.trace("Unsatified OSGi service dependencies beans " + unsatisfiedDependencies.values()); 322 synchronized (monitor) {
323 dependencyValues = new ArrayList<String>(dependencies.values());
324 }
325 log.trace("Total OSGi service dependencies beans " + dependencyValues);
326 log.trace("Unsatified OSGi service dependencies beans " + unsatisfiedDependencyValues);
296 } 327 }
297 } 328 }
298 329
@@ -332,13 +363,17 @@ public class DependencyServiceManager {
332 if (discoveredDependencies != null) 363 if (discoveredDependencies != null)
333 for (OsgiServiceDependency dependency : discoveredDependencies) { 364 for (OsgiServiceDependency dependency : discoveredDependencies) {
334 if (dependency.isMandatory()) { 365 if (dependency.isMandatory()) {
335 MandatoryServiceDependency msd = new MandatoryServiceDependency(bundleContext, dependency); 366 MandatoryServiceDependency msd = new MandatoryServiceDependency(bundleContext, dependency);
336 dependencies.put(msd, dependency.getBeanName()); 367 synchronized (monitor) {
368 dependencies.put(msd, dependency.getBeanName());
369 }
337 370
338 if (!msd.isServicePresent()) { 371 if (!msd.isServicePresent()) {
339 log.info("Adding OSGi service dependency for importer [" + msd.getBeanName() 372 log.info("Adding OSGi service dependency for importer [" + msd.getBeanName()
340 + "] matching OSGi filter [" + msd.filterAsString + "]"); 373 + "] matching OSGi filter [" + msd.filterAsString + "]");
341 unsatisfiedDependencies.put(msd, dependency.getBeanName()); 374 synchronized (monitor) {
375 unsatisfiedDependencies.put(msd, dependency.getBeanName());
376 }
342 } else { 377 } else {
343 if (debug) 378 if (debug)
344 log.debug("OSGi service dependency for importer [" + msd.getBeanName() 379 log.debug("OSGi service dependency for importer [" + msd.getBeanName()
@@ -349,12 +384,20 @@ public class DependencyServiceManager {
349 } 384 }
350 } 385 }
351 386
352 protected boolean isSatisfied() { 387 public boolean isSatisfied() {
353 return unsatisfiedDependencies.isEmpty(); 388 synchronized (monitor) {
389 return unsatisfiedDependencies.isEmpty();
390 }
354 } 391 }
355 392
356 public Map<MandatoryServiceDependency, String> getUnsatisfiedDependencies() { 393 public Map<MandatoryServiceDependency, String> getUnsatisfiedDependencies() {
357 return unsatisfiedDependencies; 394 if (isSatisfied()) {
395 return UNMODIFIABLE_DEPENDENCY_MAP;
396 } else {
397 synchronized (monitor) {
398 return Collections.unmodifiableMap(new HashMap<MandatoryServiceDependency, String>(unsatisfiedDependencies));
399 }
400 }
358 } 401 }
359 402
360 protected void register() { 403 protected void register() {
@@ -365,7 +408,7 @@ public class DependencyServiceManager {
365 } 408 }
366 409
367 // send dependency event before registering the filter 410 // send dependency event before registering the filter
368 sendInitialBootstrappingEvents(unsatisfiedDependencies.keySet()); 411 sendInitialBootstrappingEvents(getUnsatisfiedDependencies().keySet());
369 412
370 if (System.getSecurityManager() != null) { 413 if (System.getSecurityManager() != null) {
371 AccessControlContext acc = getAcc(); 414 AccessControlContext acc = getAcc();
@@ -386,12 +429,16 @@ public class DependencyServiceManager {
386 * 429 *
387 * @return 430 * @return
388 */ 431 */
389 private String createDependencyFilter() { 432 private String createDependencyFilter() {
390 return createDependencyFilter(dependencies.keySet()); 433 synchronized (monitor) {
434 return createDependencyFilter(dependencies.keySet());
435 }
391 } 436 }
392 437
393 String createUnsatisfiedDependencyFilter() { 438 String createUnsatisfiedDependencyFilter() {
394 return createDependencyFilter(unsatisfiedDependencies.keySet()); 439 synchronized (monitor) {
440 return createDependencyFilter(unsatisfiedDependencies.keySet());
441 }
395 } 442 }
396 443
397 private String createDependencyFilter(Collection<MandatoryServiceDependency> dependencies) { 444 private String createDependencyFilter(Collection<MandatoryServiceDependency> dependencies) {
@@ -425,7 +472,9 @@ public class DependencyServiceManager {
425 } 472 }
426 473
427 List<OsgiServiceDependencyEvent> getUnsatisfiedDependenciesAsEvents() { 474 List<OsgiServiceDependencyEvent> getUnsatisfiedDependenciesAsEvents() {
428 return getUnsatisfiedDependenciesAsEvents(unsatisfiedDependencies.keySet()); 475 synchronized (monitor) {
476 return getUnsatisfiedDependenciesAsEvents(unsatisfiedDependencies.keySet());
477 }
429 } 478 }
430 479
431 private List<OsgiServiceDependencyEvent> getUnsatisfiedDependenciesAsEvents( 480 private List<OsgiServiceDependencyEvent> getUnsatisfiedDependenciesAsEvents(
@@ -497,5 +546,12 @@ public class DependencyServiceManager {
497 return ((ConfigurableBeanFactory) beanFactory).getAccessControlContext(); 546 return ((ConfigurableBeanFactory) beanFactory).getAccessControlContext();
498 } 547 }
499 return null; 548 return null;
500 } 549 }
550
551 public boolean allDependenciesSatisfied() {
552 synchronized (monitor) {
553 return unsatisfiedDependencies.isEmpty();
554 }
555 }
556
501} \ No newline at end of file 557} \ No newline at end of file

Back to the top