You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by cs...@apache.org on 2013/04/15 11:43:30 UTC
svn commit: r1467916 -
/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java
Author: cschneider
Date: Mon Apr 15 09:43:29 2013
New Revision: 1467916
URL: http://svn.apache.org/r1467916
Log:
DOSGI-169 Fix synchronized block. Applying slightly changed patch with thanks to Amichai
Modified:
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java?rev=1467916&r1=1467915&r2=1467916&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java Mon Apr 15 09:43:29 2013
@@ -60,6 +60,9 @@ public class RemoteServiceAdminCore impl
private final Map<EndpointDescription, Collection<ImportRegistrationImpl>> importedServices
= new LinkedHashMap<EndpointDescription, Collection<ImportRegistrationImpl>>();
+ // Is stored in exportedServices while the export is in progress as a marker
+ private final List<ExportRegistration> exportInProgress = Collections.emptyList();
+
private BundleContext bctx;
private EventProducer eventProducer;
@@ -90,51 +93,85 @@ public class RemoteServiceAdminCore impl
}
synchronized (exportedServices) {
- // check if it is already exported ....
+ // check if it is already exported...
Collection<ExportRegistration> existingRegs = exportedServices.get(key);
+
+ // if the export is already in progress, wait for it to be complete
+ while (existingRegs == exportInProgress) {
+ try {
+ exportedServices.wait();
+ existingRegs = exportedServices.get(key);
+ } catch (InterruptedException ie) {
+ LOG.debug("interrupted while waiting for export in progress");
+ return Collections.emptyList();
+ }
+ }
+
+ // if the export is complete, return a copy of existing export
if (existingRegs != null) {
LOG.debug("already exported this service. Returning existing exportRegs {} ", interfaces);
return copyExportRegistration(existingRegs);
}
- LOG.info("interfaces selected for export: " + interfaces);
- List<ExportRegistration> exportRegs = new ArrayList<ExportRegistration>(1);
- Object serviceObject = bctx.getService(serviceReference);
- BundleContext callingContext = serviceReference.getBundle().getBundleContext();
- ConfigurationTypeHandler handler = null;
- try {
- handler = configTypeHandlerFactory.getHandler(bctx, serviceProperties);
- } catch (RuntimeException e) {
- LOG.error(e.getMessage(), e);
- return Collections.emptyList();
- }
- // FIXME: move out of synchronized ... -> blocks until publication is finished
- for (String iface : interfaces) {
- LOG.info("creating server for interface " + iface);
- // this is an extra sanity check, but do we really need it now ?
- Class<?> interfaceClass = ClassUtils.getInterfaceClass(serviceObject, iface);
- if (interfaceClass != null) {
- ExportResult exportResult = handler.createServer(serviceReference, bctx, callingContext,
- serviceProperties, interfaceClass, serviceObject);
- LOG.info("created server for interface " + iface);
- EndpointDescription epd = new EndpointDescription(exportResult.getEndpointProps());
- ExportRegistrationImpl exportRegistration = new ExportRegistrationImpl(serviceReference, epd, this);
- if (exportResult.getException() == null) {
- exportRegistration.setServer(exportResult.getServer());
- exportRegistration.startServiceTracker(bctx);
- } else {
- LOG.error(exportResult.getException().getMessage(), exportResult.getException());
- exportRegistration.setException(exportResult.getException());
- }
- exportRegs.add(exportRegistration);
- }
- }
+ // mark export as being in progress
+ exportedServices.put(key, exportInProgress);
+ }
- // enlist initial export Registrations in global list of exportRegistrations
- exportedServices.put(key, new ArrayList<ExportRegistration>(exportRegs));
+ try {
+ // do the export
+ List<ExportRegistration> exportRegs = exportInterfaces(interfaces, serviceReference, serviceProperties);
+
+ // enlist initial export registrations in global list of exportRegistrations
+ synchronized (exportedServices) {
+ exportedServices.put(key, new ArrayList<ExportRegistration>(exportRegs));
+ }
eventProducer.publishNotifcation(exportRegs);
return exportRegs;
+ } finally {
+ synchronized (exportedServices) {
+ if (exportedServices.get(key) == exportInProgress) {
+ exportedServices.remove(key);
+ }
+ exportedServices.notifyAll(); // in any case, always notify waiting threads
+ }
+ }
+ }
+
+ private List<ExportRegistration> exportInterfaces(List<String> interfaces,
+ ServiceReference serviceReference, Map<String, Object> serviceProperties) {
+ LOG.info("interfaces selected for export: " + interfaces);
+ ConfigurationTypeHandler handler;
+ try {
+ handler = configTypeHandlerFactory.getHandler(bctx, serviceProperties);
+ } catch (RuntimeException e) {
+ LOG.error(e.getMessage(), e);
+ return Collections.emptyList();
+ }
+ List<ExportRegistration> exportRegs = new ArrayList<ExportRegistration>(1);
+ Object serviceObject = bctx.getService(serviceReference);
+ BundleContext callingContext = serviceReference.getBundle().getBundleContext();
+
+ for (String iface : interfaces) {
+ LOG.info("creating server for interface " + iface);
+ // this is an extra sanity check, but do we really need it now ?
+ Class<?> interfaceClass = ClassUtils.getInterfaceClass(serviceObject, iface);
+ if (interfaceClass != null) {
+ ExportResult exportResult = handler.createServer(serviceReference, bctx, callingContext,
+ serviceProperties, interfaceClass, serviceObject);
+ LOG.info("created server for interface " + iface);
+ EndpointDescription epd = new EndpointDescription(exportResult.getEndpointProps());
+ ExportRegistrationImpl exportRegistration = new ExportRegistrationImpl(serviceReference, epd, this);
+ if (exportResult.getException() == null) {
+ exportRegistration.setServer(exportResult.getServer());
+ exportRegistration.startServiceTracker(bctx);
+ } else {
+ LOG.error(exportResult.getException().getMessage(), exportResult.getException());
+ exportRegistration.setException(exportResult.getException());
+ }
+ exportRegs.add(exportRegistration);
+ }
}
+ return exportRegs;
}
/**