/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.util; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.tmatesoft.svn.util.SVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; /** * @version 1.3 * @author TMate Software Ltd. */ public class SVNThreadPool implements ISVNThreadPool { private ThreadPoolExecutor myThreadPool; private CustomThreadFactory myThreadFactory; private ISVNThreadPool myFailSafePool; public ISVNTask run(Runnable task, boolean daemon) { ThreadPoolExecutor threadPool = getThreadPool(daemon); try { Future<?> future = threadPool.submit(task); return new SVNTask(future); } catch (RejectedExecutionException e) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.DEFAULT, "Could not submit task: " + e.getMessage()); } ISVNThreadPool failSafePool = getFailSafePool(); return failSafePool.run(task, daemon); } private synchronized ISVNThreadPool getFailSafePool() { if (myFailSafePool == null) { myFailSafePool = new SVNEmptyThreadPool(); } return myFailSafePool; } private synchronized ThreadPoolExecutor getThreadPool(boolean daemon) { CustomThreadFactory threadFactory = getThreadFactory(daemon); if (myThreadPool == null) { myThreadPool = new ThreadPoolExecutor(2, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); } return myThreadPool; } private synchronized CustomThreadFactory getThreadFactory(boolean daemon) { if (myThreadFactory == null) { myThreadFactory = new CustomThreadFactory(daemon); } else { myThreadFactory.setIsDaemon(daemon); } return myThreadFactory; } private static class CustomThreadFactory implements ThreadFactory { private static final AtomicInteger ourPoolNumber = new AtomicInteger(1); private final ThreadGroup myGroup; private final AtomicInteger myThreadNumber = new AtomicInteger(1); private final String myNamePrefix; private boolean myIsDaemon; CustomThreadFactory(boolean daemon) { SecurityManager s = System.getSecurityManager(); myGroup = (s != null)? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); myNamePrefix = "pool-" + ourPoolNumber.getAndIncrement() + "-svnkit-thread-"; myIsDaemon = daemon; } public void setIsDaemon(boolean isDaemon) { myIsDaemon = isDaemon; } public Thread newThread(Runnable task) { Thread thread = new Thread(myGroup, task, myNamePrefix + myThreadNumber.getAndIncrement(), 0); thread.setDaemon(myIsDaemon); if (thread.getPriority() != Thread.NORM_PRIORITY) { thread.setPriority(Thread.NORM_PRIORITY); } return thread; } } }