diff --git a/core/src/main/java/org/fourthline/cling/DefaultUpnpServiceConfiguration.java b/core/src/main/java/org/fourthline/cling/DefaultUpnpServiceConfiguration.java index e894aa67a..38e5fb37d 100644 --- a/core/src/main/java/org/fourthline/cling/DefaultUpnpServiceConfiguration.java +++ b/core/src/main/java/org/fourthline/cling/DefaultUpnpServiceConfiguration.java @@ -148,11 +148,13 @@ public GENAEventProcessor getGenaEventProcessor() { } public StreamClient createStreamClient() { - return new StreamClientImpl( - new StreamClientConfigurationImpl( + StreamClientConfigurationImpl configuration = new StreamClientConfigurationImpl( getSyncProtocolExecutorService() - ) ); + + configuration.setTimeoutSeconds((int) (getThreadTimeoutInMilliseconds() / 1000)); + + return new StreamClientImpl(configuration); } public MulticastReceiver createMulticastReceiver(NetworkAddressFactory networkAddressFactory) { @@ -257,6 +259,15 @@ public NetworkAddressFactory createNetworkAddressFactory() { return createNetworkAddressFactory(streamListenPort); } + public long getThreadTimeoutInMilliseconds() { + try { + return Long.parseLong(System.getProperty("cling.thread_timeout", "60000")); + } + catch (NumberFormatException e) { + return 60000L; + } + } + public void shutdown() { log.fine("Shutting down default executor service"); getDefaultExecutorService().shutdownNow(); @@ -295,12 +306,12 @@ protected ExecutorService getDefaultExecutorService() { } protected ExecutorService createDefaultExecutorService() { - return new ClingExecutor(); + return new ClingExecutor(getThreadTimeoutInMilliseconds()); } public static class ClingExecutor extends ThreadPoolExecutor { - public ClingExecutor() { + public ClingExecutor(long timeoutInMilliseconds) { this(new ClingThreadFactory(), new ThreadPoolExecutor.DiscardPolicy() { // The pool is unbounded but rejections will happen during shutdown @@ -310,16 +321,17 @@ public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolEx log.info("Thread pool rejected execution of " + runnable.getClass()); super.rejectedExecution(runnable, threadPoolExecutor); } - } + }, + timeoutInMilliseconds ); } - public ClingExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedHandler) { + public ClingExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedHandler, long timeoutInMilliseconds) { // This is the same as Executors.newCachedThreadPool super(0, Integer.MAX_VALUE, - 60L, - TimeUnit.SECONDS, + timeoutInMilliseconds, + TimeUnit.MILLISECONDS, new SynchronousQueue(), threadFactory, rejectedHandler diff --git a/core/src/main/java/org/fourthline/cling/ManagedUpnpServiceConfiguration.java b/core/src/main/java/org/fourthline/cling/ManagedUpnpServiceConfiguration.java index 3166fce2d..d35c07e16 100644 --- a/core/src/main/java/org/fourthline/cling/ManagedUpnpServiceConfiguration.java +++ b/core/src/main/java/org/fourthline/cling/ManagedUpnpServiceConfiguration.java @@ -217,6 +217,16 @@ public Executor getRegistryListenerExecutor() { return getDefaultExecutorService(); } + @Override + public long getThreadTimeoutInMilliseconds() { + try { + return Long.parseLong(System.getProperty("cling.thread_timeout", "60000")); + } + catch (NumberFormatException e) { + return 60000L; + } + } + public NetworkAddressFactory createNetworkAddressFactory() { return createNetworkAddressFactory(streamListenPort); } @@ -255,6 +265,6 @@ protected ExecutorService getDefaultExecutorService() { } protected ExecutorService createDefaultExecutorService() { - return new DefaultUpnpServiceConfiguration.ClingExecutor(); + return new DefaultUpnpServiceConfiguration.ClingExecutor(getThreadTimeoutInMilliseconds()); } } diff --git a/core/src/main/java/org/fourthline/cling/UpnpServiceConfiguration.java b/core/src/main/java/org/fourthline/cling/UpnpServiceConfiguration.java index 0f0697962..b860665aa 100644 --- a/core/src/main/java/org/fourthline/cling/UpnpServiceConfiguration.java +++ b/core/src/main/java/org/fourthline/cling/UpnpServiceConfiguration.java @@ -248,6 +248,11 @@ public interface UpnpServiceConfiguration { */ public Executor getRegistryListenerExecutor(); + /** + * @return The timeout for thread connections + */ + public long getThreadTimeoutInMilliseconds(); + /** * Called by the {@link org.fourthline.cling.UpnpService} on shutdown, useful to e.g. shutdown thread pools. */ diff --git a/core/src/main/java/org/fourthline/cling/android/AndroidRouter.java b/core/src/main/java/org/fourthline/cling/android/AndroidRouter.java index 7ebb1b179..42e12fce3 100644 --- a/core/src/main/java/org/fourthline/cling/android/AndroidRouter.java +++ b/core/src/main/java/org/fourthline/cling/android/AndroidRouter.java @@ -74,7 +74,7 @@ protected BroadcastReceiver createConnectivityBroadcastReceiver() { @Override protected int getLockTimeoutMillis() { - return 15000; + return (int) (getConfiguration().getThreadTimeoutInMilliseconds() + 5000); } @Override