diff options
author | slewis | 2011-04-05 14:28:35 +0000 |
---|---|---|
committer | slewis | 2011-04-05 14:28:35 +0000 |
commit | db92d2c90cad8ec50ced83ea3d18db81b12a7864 (patch) | |
tree | 52e16f197fcc8d2b7ddbbd57a699f5b0d1deb40f | |
parent | d895036212e449944c59dfce84bdbe1ea06d0534 (diff) | |
download | org.eclipse.ecf-db92d2c90cad8ec50ced83ea3d18db81b12a7864.tar.gz org.eclipse.ecf-db92d2c90cad8ec50ced83ea3d18db81b12a7864.tar.xz org.eclipse.ecf-db92d2c90cad8ec50ced83ea3d18db81b12a7864.zip |
Fix for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=341818
2 files changed, 68 insertions, 6 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/Activator.java b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/Activator.java index 8c2650bb1..e5d33c2bb 100644 --- a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/Activator.java +++ b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/Activator.java @@ -12,8 +12,8 @@ package org.eclipse.ecf.internal.provider.r_osgi; import ch.ethz.iks.r_osgi.RemoteOSGiService; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; +import org.eclipse.equinox.concurrent.future.IExecutor; +import org.osgi.framework.*; import org.osgi.util.tracker.ServiceTracker; /** @@ -23,6 +23,17 @@ import org.osgi.util.tracker.ServiceTracker; */ public final class Activator implements BundleActivator { + // This is a service property that is used to find any IExecutor service instances + // to be used for synchronous or asynchronous execution. The use of the IExecutor + // The type of the value for this property is String, and valid values are 'sync' or 'async' + // For example, to setup one's own executor implementation to use for async invocation + // on a consumer would look like this + // + // props.put("org.eclipse.ecf.provider.r_osgi.consumerExecutor","async"); + // bundleContext.registerService(IExecutor.class.getName(), new MyExecutor(), props); + // + public static final String CONSUMER_SYNC_EXECUTOR_TYPE = "org.eclipse.ecf.provider.r_osgi.consumerExecutor"; //$NON-NLS-1$ + // The plug-in ID public static final String PLUGIN_ID = "org.eclipse.ecf.provider.r_osgi"; //$NON-NLS-1$ @@ -65,6 +76,12 @@ public final class Activator implements BundleActivator { public void stop(final BundleContext bc) throws Exception { r_osgi_tracker.close(); r_osgi_tracker = null; + synchronized (executorServiceTrackerLock) { + if (executorServiceTracker != null) { + executorServiceTracker.close(); + executorServiceTracker = null; + } + } this.context = null; plugin = null; } @@ -101,4 +118,27 @@ public final class Activator implements BundleActivator { } return plugin; } + + private ServiceTracker executorServiceTracker; + private final Object executorServiceTrackerLock = new Object(); + + private Filter createExecutorFilter(boolean sync) { + try { + return getContext().createFilter("(&(" + Constants.OBJECTCLASS + "=" + IExecutor.class.getName() + ")(" + CONSUMER_SYNC_EXECUTOR_TYPE + "=" + ((sync) ? "sync" : "async") + "))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ + } catch (InvalidSyntaxException e) { + // should not happen + return null; + } + } + + public IExecutor getExecutor(boolean sync) { + synchronized (executorServiceTrackerLock) { + if (executorServiceTracker == null) { + Filter syncExecutorFilter = createExecutorFilter(sync); + executorServiceTracker = new ServiceTracker(getContext(), syncExecutorFilter, null); + executorServiceTracker.open(); + } + } + return (IExecutor) executorServiceTracker.getService(); + } } diff --git a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java index 0a5ab38d8..0e05ded28 100644 --- a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java +++ b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java @@ -83,14 +83,37 @@ final class RemoteServiceImpl extends AbstractRemoteService { * @see org.eclipse.ecf.remoteservice.IRemoteService#callAsync(org.eclipse.ecf.remoteservice.IRemoteCall) */ public IFuture callAsync(final IRemoteCall call) { - final AbstractExecutor executor = new ThreadsExecutor(); - return executor.execute(new IProgressRunnable() { + return getAsyncExecutor().execute(new IProgressRunnable() { public Object run(IProgressMonitor monitor) throws Exception { return callSync(call); } }, null); } + private IExecutor asyncExecutor; + private IExecutor syncExecutor; + private final Object executorLock = new Object(); + + private IExecutor getAsyncExecutor() { + synchronized (executorLock) { + if (asyncExecutor == null) { + IExecutor executor = Activator.getDefault().getExecutor(false); + asyncExecutor = (executor == null) ? new ThreadsExecutor() : executor; + } + return asyncExecutor; + } + } + + private IExecutor getSyncExecutor() { + synchronized (executorLock) { + if (syncExecutor == null) { + IExecutor executor = Activator.getDefault().getExecutor(true); + syncExecutor = (executor == null) ? new ImmediateExecutor() : executor; + } + return syncExecutor; + } + } + /** * call the service synchronously. * @@ -106,8 +129,7 @@ final class RemoteServiceImpl extends AbstractRemoteService { for (int i = 0; i < formalParams.length; i++) { formalParams[i] = call.getParameters()[i].getClass(); } - IExecutor executor = new ThreadsExecutor(); - IFuture future = executor.execute(new IProgressRunnable() { + IFuture future = getSyncExecutor().execute(new IProgressRunnable() { public Object run(IProgressMonitor monitor) throws Exception { final Method method = ClassUtil.getMethod(service.getClass(), call.getMethod(), formalParams); return method.invoke(service, parameters); |