Author: remm Date: Wed Nov 28 12:55:32 2018 New Revision: 1847635 URL: http://svn.apache.org/viewvc?rev=1847635&view=rev Log: Refactor the utility scheduled executor from the Service to the Server as I got a usecase for ha.backend.HeartbeatListener as a Server listener.
Modified: tomcat/trunk/java/org/apache/catalina/Server.java tomcat/trunk/java/org/apache/catalina/Service.java tomcat/trunk/java/org/apache/catalina/connector/Connector.java tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/core/StandardServer.java tomcat/trunk/java/org/apache/catalina/core/StandardService.java tomcat/trunk/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java tomcat/trunk/webapps/docs/changelog.xml tomcat/trunk/webapps/docs/config/host.xml tomcat/trunk/webapps/docs/config/server.xml tomcat/trunk/webapps/docs/config/service.xml Modified: tomcat/trunk/java/org/apache/catalina/Server.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Server.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Server.java (original) +++ tomcat/trunk/java/org/apache/catalina/Server.java Wed Nov 28 12:55:32 2018 @@ -19,6 +19,7 @@ package org.apache.catalina; import java.io.File; +import java.util.concurrent.ScheduledExecutorService; import org.apache.catalina.deploy.NamingResourcesImpl; import org.apache.catalina.startup.Catalina; @@ -204,6 +205,20 @@ public interface Server extends Lifecycl public void setCatalinaHome(File catalinaHome); + /** + * Get the utility thread count. + * @return the thread count + */ + public int getUtilityThreads(); + + + /** + * Set the utility thread count. + * @param utilityThreads the new thread count + */ + public void setUtilityThreads(int utilityThreads); + + // --------------------------------------------------------- Public Methods @@ -250,4 +265,10 @@ public interface Server extends Lifecycl * context. */ public Object getNamingToken(); + + /** + * @return the utility executor managed by the Service. + */ + public ScheduledExecutorService getUtilityExecutor(); + } Modified: tomcat/trunk/java/org/apache/catalina/Service.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Service.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Service.java (original) +++ tomcat/trunk/java/org/apache/catalina/Service.java Wed Nov 28 12:55:32 2018 @@ -18,8 +18,6 @@ package org.apache.catalina; -import java.util.concurrent.ScheduledExecutorService; - import org.apache.catalina.connector.Connector; import org.apache.catalina.mapper.Mapper; @@ -98,20 +96,6 @@ public interface Service extends Lifecyc public String getDomain(); - /** - * Get the utility thread count. - * @return the thread count - */ - public int getUtilityThreads(); - - - /** - * Set the utility thread count. - * @param utilityThreads the new thread count - */ - public void setUtilityThreads(int utilityThreads); - - // --------------------------------------------------------- Public Methods /** @@ -168,9 +152,4 @@ public interface Service extends Lifecyc */ Mapper getMapper(); - /** - * @return the utility executor managed by the Service. - */ - ScheduledExecutorService getUtilityExecutor(); - } Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Connector.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Connector.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Connector.java Wed Nov 28 12:55:32 2018 @@ -949,7 +949,7 @@ public class Connector extends Lifecycle adapter = new CoyoteAdapter(this); protocolHandler.setAdapter(adapter); if (service != null) { - protocolHandler.setUtilityExecutor(service.getUtilityExecutor()); + protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor()); } // Make sure parseBodyMethodsSet has a default Modified: tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java Wed Nov 28 12:55:32 2018 @@ -52,7 +52,7 @@ import org.apache.catalina.LifecycleStat import org.apache.catalina.Loader; import org.apache.catalina.Pipeline; import org.apache.catalina.Realm; -import org.apache.catalina.Service; +import org.apache.catalina.Server; import org.apache.catalina.Valve; import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; @@ -873,9 +873,9 @@ public abstract class ContainerBase exte } } else { // Delegate utility execution to the Service - Service service = Container.getService(this); - service.setUtilityThreads(threads); - startStopExecutor = Container.getService(this).getUtilityExecutor(); + Server server = Container.getService(this).getServer(); + server.setUtilityThreads(threads); + startStopExecutor = server.getUtilityExecutor(); } } @@ -937,7 +937,7 @@ public abstract class ContainerBase exte // Start our thread if (backgroundProcessorDelay > 0) { - monitorFuture = Container.getService(ContainerBase.this) + monitorFuture = Container.getService(ContainerBase.this).getServer() .getUtilityExecutor().scheduleWithFixedDelay( new ContainerBackgroundProcessorMonitor(), 0, 60, TimeUnit.SECONDS); } @@ -1278,7 +1278,7 @@ public abstract class ContainerBase exte log.error(sm.getString("containerBase.backgroundProcess.error"), e); } } - backgroundProcessorFuture = Container.getService(this).getUtilityExecutor() + backgroundProcessorFuture = Container.getService(this).getServer().getUtilityExecutor() .scheduleWithFixedDelay(new ContainerBackgroundProcessor(), backgroundProcessorDelay, backgroundProcessorDelay, TimeUnit.SECONDS); Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties [UTF-8] (original) +++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties [UTF-8] Wed Nov 28 12:55:32 2018 @@ -221,6 +221,7 @@ standardHostValue.customStatusFailed=Cus standardServer.accept.timeout=The socket listening for the shutdown command experienced an unexpected timeout [{0}] milliseconds after the call to accept(). Is this an instance of bug 56684? standardServer.awaitSocket.fail=Failed to create server shutdown socket on address [{0}] and port [{1}] (base port [{2}] and offset [{3}]) +standardServer.periodicEventError=Error sending periodic event standardServer.portOffset.invalid=The value [{0}] for portOffset is not valid as portOffset may not be negative standardServer.shutdownViaPort=A valid shutdown command was received via the shutdown port. Stopping the Server instance. standardServer.storeConfig.notAvailable=No StoreConfig implementation was registered as an MBean named [{0}] so no configuration could be saved. A suitable MBean is normally registered via the StoreConfigLifecycleListener. Modified: tomcat/trunk/java/org/apache/catalina/core/StandardServer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardServer.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardServer.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardServer.java Wed Nov 28 12:55:32 2018 @@ -30,12 +30,18 @@ import java.net.URL; import java.net.URLClassLoader; import java.security.AccessControlException; import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.ObjectName; import org.apache.catalina.Context; +import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleState; import org.apache.catalina.Server; @@ -51,6 +57,7 @@ import org.apache.juli.logging.LogFactor import org.apache.tomcat.util.ExceptionUtils; import org.apache.tomcat.util.buf.StringCache; import org.apache.tomcat.util.res.StringManager; +import org.apache.tomcat.util.threads.TaskThreadFactory; /** @@ -175,6 +182,39 @@ public final class StandardServer extend private final Object namingToken = new Object(); + /** + * The number of threads available to process utility tasks in this service. + */ + protected int utilityThreads = 1; + + /** + * The utility threads daemon flag. + */ + protected boolean utilityThreadsAsDaemon = false; + + /** + * Utility executor with scheduling capabilities. + */ + private ScheduledThreadPoolExecutor utilityExecutor = null; + + /** + * Utility executor wrapper. + */ + private ScheduledExecutorService utilityExecutorWrapper = null; + + + /** + * Controller for the periodic lifecycle event. + */ + private ScheduledFuture<?> periodicLifecycleEventFuture = null; + private ScheduledFuture<?> monitorFuture; + + + /** + * The event period. + */ + protected int eventPeriod = 10; + // ------------------------------------------------------------- Properties @@ -364,6 +404,99 @@ public final class StandardServer extend this.catalina = catalina; } + + @Override + public int getUtilityThreads() { + return utilityThreads; + } + + + /** + * Handles the special values. + */ + private static int getUtilityThreadsInternal(int utilityThreads) { + int result = utilityThreads; + if (result > 0) { + return result; + } + + // Zero == Runtime.getRuntime().availableProcessors() / 2 + // -ve == Runtime.getRuntime().availableProcessors() / 2 + value + // These two are the same + result = (Runtime.getRuntime().availableProcessors() / 2) + result; + if (result < 1) { + result = 1; + } + return result; + } + + @Override + public void setUtilityThreads(int utilityThreads) { + if (getUtilityThreadsInternal(utilityThreads) < getUtilityThreadsInternal(this.utilityThreads)) { + return; + } + int oldUtilityThreads = this.utilityThreads; + this.utilityThreads = utilityThreads; + + // Use local copies to ensure thread safety + if (oldUtilityThreads != utilityThreads && utilityExecutor != null) { + reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads)); + } + } + + + private synchronized void reconfigureUtilityExecutor(int threads) { + // The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, only CorePoolSize is available + if (utilityExecutor != null) { + utilityExecutor.setCorePoolSize(threads); + } else { + ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = + new ScheduledThreadPoolExecutor(threads, + new TaskThreadFactory("Catalina-utility-", utilityThreadsAsDaemon, Thread.NORM_PRIORITY)); + scheduledThreadPoolExecutor.setKeepAliveTime(10, TimeUnit.SECONDS); + scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true); + scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + utilityExecutor = scheduledThreadPoolExecutor; + utilityExecutorWrapper = new org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(utilityExecutor); + } + } + + + /** + * Get if the utility threads are daemon threads. + * @return the threads daemon flag + */ + public boolean getUtilityThreadsAsDaemon() { + return utilityThreadsAsDaemon; + } + + + /** + * Set the utility threads daemon flag. The default value is true. + * @param utilityThreadsAsDaemon the new thread daemon flag + */ + public void setUtilityThreadsAsDaemon(boolean utilityThreadsAsDaemon) { + this.utilityThreadsAsDaemon = utilityThreadsAsDaemon; + } + + + /** + * @return The period between two events, in seconds + */ + public int getEventPeriod() { + return eventPeriod; + } + + + /** + * Set the new period between two events. + * @param eventPeriod The period in seconds, <= 0 disables events + */ + public final void setEventPeriod(int eventPeriod) { + this.eventPeriod = eventPeriod; + } + + // --------------------------------------------------------- Server Methods @@ -801,6 +934,37 @@ public final class StandardServer extend services[i].start(); } } + + if (eventPeriod > 0) { + monitorFuture = getUtilityExecutor().scheduleWithFixedDelay( + new Runnable() { + @Override + public void run() { + startPeriodicLifecycleEvent(); + } + }, 0, 60, TimeUnit.SECONDS); + } + } + + + protected void startPeriodicLifecycleEvent() { + if (periodicLifecycleEventFuture == null || (periodicLifecycleEventFuture != null && periodicLifecycleEventFuture.isDone())) { + if (periodicLifecycleEventFuture != null && periodicLifecycleEventFuture.isDone()) { + // There was an error executing the scheduled task, get it and log it + try { + periodicLifecycleEventFuture.get(); + } catch (InterruptedException | ExecutionException e) { + log.error(sm.getString("standardServer.periodicEventError"), e); + } + } + periodicLifecycleEventFuture = getUtilityExecutor().scheduleAtFixedRate( + new Runnable() { + @Override + public void run() { + fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null); + } + }, eventPeriod, eventPeriod, TimeUnit.SECONDS); + } } @@ -815,6 +979,16 @@ public final class StandardServer extend protected void stopInternal() throws LifecycleException { setState(LifecycleState.STOPPING); + + if (monitorFuture != null) { + monitorFuture.cancel(true); + monitorFuture = null; + } + if (periodicLifecycleEventFuture != null) { + periodicLifecycleEventFuture.cancel(false); + periodicLifecycleEventFuture = null; + } + fireLifecycleEvent(CONFIGURE_STOP_EVENT, null); // Stop our defined Services @@ -836,6 +1010,10 @@ public final class StandardServer extend super.initInternal(); + // Initialize utility executor + reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads)); + register(utilityExecutor, "type=UtilityExecutor"); + // Register global String cache // Note although the cache is global, if there are multiple Servers // present in the JVM (may happen when embedding) then the same cache @@ -897,6 +1075,12 @@ public final class StandardServer extend unregister(onameStringCache); + if (utilityExecutor != null) { + utilityExecutor.shutdownNow(); + unregister("type=UtilityExecutor"); + utilityExecutor = null; + } + super.destroyInternal(); } @@ -958,4 +1142,10 @@ public final class StandardServer extend protected final String getObjectNameKeyProperties() { return "type=Server"; } + + @Override + public ScheduledExecutorService getUtilityExecutor() { + return utilityExecutorWrapper; + } + } Modified: tomcat/trunk/java/org/apache/catalina/core/StandardService.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardService.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardService.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardService.java Wed Nov 28 12:55:32 2018 @@ -20,9 +20,6 @@ package org.apache.catalina.core; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import javax.management.ObjectName; @@ -41,7 +38,6 @@ import org.apache.catalina.util.Lifecycl import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; -import org.apache.tomcat.util.threads.TaskThreadFactory; /** @@ -93,26 +89,6 @@ public class StandardService extends Lif */ protected final ArrayList<Executor> executors = new ArrayList<>(); - /** - * The number of threads available to process utility tasks in this service. - */ - protected int utilityThreads = 1; - - /** - * The utility threads daemon flag. - */ - protected boolean utilityThreadsAsDaemon = false; - - /** - * Utility executor with scheduling capabilities. - */ - private ScheduledThreadPoolExecutor utilityExecutor = null; - - /** - * Utility executor wrapper. - */ - private ScheduledExecutorService utilityExecutorWrapper = null; - private Engine engine = null; private ClassLoader parentClassLoader = null; @@ -226,81 +202,6 @@ public class StandardService extends Lif } - @Override - public int getUtilityThreads() { - return utilityThreads; - } - - - /** - * Handles the special values. - */ - private static int getUtilityThreadsInternal(int utilityThreads) { - int result = utilityThreads; - if (result > 0) { - return result; - } - - // Zero == Runtime.getRuntime().availableProcessors() / 2 - // -ve == Runtime.getRuntime().availableProcessors() / 2 + value - // These two are the same - result = (Runtime.getRuntime().availableProcessors() / 2) + result; - if (result < 1) { - result = 1; - } - return result; - } - - @Override - public void setUtilityThreads(int utilityThreads) { - if (getUtilityThreadsInternal(utilityThreads) < getUtilityThreadsInternal(this.utilityThreads)) { - return; - } - int oldUtilityThreads = this.utilityThreads; - this.utilityThreads = utilityThreads; - - // Use local copies to ensure thread safety - if (oldUtilityThreads != utilityThreads && utilityExecutor != null) { - reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads)); - } - } - - - private synchronized void reconfigureUtilityExecutor(int threads) { - // The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, only CorePoolSize is available - if (utilityExecutor != null) { - utilityExecutor.setCorePoolSize(threads); - } else { - ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = - new ScheduledThreadPoolExecutor(threads, - new TaskThreadFactory(getName() + "-utility-", utilityThreadsAsDaemon, Thread.NORM_PRIORITY)); - scheduledThreadPoolExecutor.setKeepAliveTime(10, TimeUnit.SECONDS); - scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true); - scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); - utilityExecutor = scheduledThreadPoolExecutor; - utilityExecutorWrapper = new org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(utilityExecutor); - } - } - - - /** - * Get if the utility threads are daemon threads. - * @return the threads daemon flag - */ - public boolean getUtilityThreadsAsDaemon() { - return utilityThreadsAsDaemon; - } - - - /** - * Set the utility threads daemon flag. The default value is true. - * @param utilityThreadsAsDaemon the new thread daemon flag - */ - public void setUtilityThreadsAsDaemon(boolean utilityThreadsAsDaemon) { - this.utilityThreadsAsDaemon = utilityThreadsAsDaemon; - } - - // --------------------------------------------------------- Public Methods @@ -613,9 +514,6 @@ public class StandardService extends Lif super.initInternal(); - reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads)); - register(utilityExecutor, "type=UtilityExecutor"); - if (engine != null) { engine.init(); } @@ -660,12 +558,6 @@ public class StandardService extends Lif engine.destroy(); } - if (utilityExecutor != null) { - utilityExecutor.shutdownNow(); - unregister("type=UtilityExecutor"); - utilityExecutor = null; - } - super.destroyInternal(); } @@ -724,9 +616,4 @@ public class StandardService extends Lif return "type=Service"; } - @Override - public ScheduledExecutorService getUtilityExecutor() { - return utilityExecutorWrapper; - } - } Modified: tomcat/trunk/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java Wed Nov 28 12:55:32 2018 @@ -527,7 +527,7 @@ public class SimpleTcpCluster extends Li name.append(",component=Deployer"); onameClusterDeployer = register(clusterDeployer, name.toString()); } - channel.setUtilityExecutor(Container.getService(getContainer()).getUtilityExecutor()); + channel.setUtilityExecutor(Container.getService(getContainer()).getServer().getUtilityExecutor()); } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Wed Nov 28 12:55:32 2018 @@ -61,16 +61,16 @@ (remm) </fix> <add> - Add a scheduled executor to the Service, which can be used to + Add a scheduled executor to the Server, which can be used to process periodic utility tasks. The utility threads are non daemon by default. (remm) </add> <update> - Refactor container background processor using the Service executor, and + Refactor container background processor using the Server executor, and add monitoring to reschedule it in case of an unexpected error. (remm) </update> <update> - Refactor parallel deployment threads using the Service executor. (remm) + Refactor parallel deployment threads using the Server executor. (remm) </update> <add> Introduce a ConfigurationSource API to standardize access to the core Modified: tomcat/trunk/webapps/docs/config/host.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/host.xml?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/host.xml (original) +++ tomcat/trunk/webapps/docs/config/host.xml Wed Nov 28 12:55:32 2018 @@ -141,7 +141,7 @@ and all its child containers. A host will use background processing to perform live web application deployment related tasks. If not specified, the default value for this attribute is -1, which means - the host will rely on the background processing thread of its parent + the host will rely on the background processing setting of its parent engine.</p> </attribute> @@ -204,8 +204,8 @@ thread pool will be used to deploy new <a href="context.html">Context</a>s if automatic deployment is being used. - As the thread pool is shared at the service level, if more than one - host specifies this setting, only the maximum value will apply and will + As the thread pool is shared at the Server level, if more than one + Host specifies this setting, only the maximum value will apply and will be used for all except for the special value 1. If not specified, the default value of 1 will be used. If 1 thread is used then rather than using an <code>ExecutorService</code> the current Modified: tomcat/trunk/webapps/docs/config/server.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/server.xml?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/server.xml (original) +++ tomcat/trunk/webapps/docs/config/server.xml Wed Nov 28 12:55:32 2018 @@ -86,6 +86,18 @@ to the specified port number, in order to shut down Tomcat.</p> </attribute> + <attribute name="utilityThreads" required="false"> + <p>The number of threads this <strong>Service</strong> will use for + various utility tasks, including recurring ones. The special value + of 0 will result in the value of + <code>Runtime.getRuntime().availableProcessors()/2</code> being + used. Negative values will result in + <code>Runtime.getRuntime().availableProcessors()/2 + value</code> being + used unless this is less than 1 in which case 1 thread will be used. + The default value is 1. + </p> + </attribute> + </attributes> </subsection> @@ -98,6 +110,13 @@ common attributes listed above):</p> <attributes> + + <attribute name="utilityThreadsAsDaemon" required="false"> + <p>Set the daemon flag value for the utility threads. The default value + is <code>false</code>. + </p> + </attribute> + </attributes> </subsection> Modified: tomcat/trunk/webapps/docs/config/service.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/service.xml?rev=1847635&r1=1847634&r2=1847635&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/service.xml (original) +++ tomcat/trunk/webapps/docs/config/service.xml Wed Nov 28 12:55:32 2018 @@ -68,17 +68,6 @@ must be unique.</p> </attribute> - <attribute name="utilityThreads" required="false"> - <p>The number of threads this <strong>Service</strong> will use for - various utility tasks, including recurring ones. The special value - of 0 will result in the value of - <code>Runtime.getRuntime().availableProcessors()/2</code> being - used. Negative values will result in - <code>Runtime.getRuntime().availableProcessors()/2 + value</code> being - used unless this is less than 1 in which case 1 thread will be used. - </p> - </attribute> - </attributes> </subsection> @@ -91,13 +80,6 @@ common attributes listed above):</p> <attributes> - - <attribute name="utilityThreadsAsDaemon" required="false"> - <p>Set the daemon flag value for the utility threads. The default value - is <code>false</code>. - </p> - </attribute> - </attributes> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org