001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2008 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: SMSThreadPool.java,v 1.5 2008/08/28 19:08:22 arviranga Exp $
026 *
027 */
028
029package com.sun.identity.sm;
030
031import com.sun.identity.shared.Constants;
032import com.sun.identity.common.ShutdownListener;
033import com.sun.identity.common.ShutdownManager;
034import com.sun.identity.shared.debug.Debug;
035
036import com.iplanet.am.util.SystemProperties;
037import com.iplanet.am.util.ThreadPool;
038import com.iplanet.am.util.ThreadPoolException;
039
040/**
041 * The class <code>SMSThreadPool</code> provides interfaces to manage
042 * notfication thread pools shared by idm and sm. 
043 *
044 * @supported.api
045 */
046public class SMSThreadPool {
047    
048    private static ThreadPool thrdPool;
049    private static ShutdownListener shutdownListener;
050    private static int poolSize;
051    
052    private static Debug debug = Debug.getInstance("amSMS");
053
054    private static final int DEFAULT_POOL_SIZE = 10;
055
056    private static final int DEFAULT_TRESHOLD= 0;
057
058    private static volatile boolean initialized = false;
059
060    static synchronized void initialize(boolean reinit) {
061        // Check if already initialized
062        if (reinit) {
063            initialized = false;
064        }
065        if (initialized) {
066            return;
067        }
068        int newPoolSize = DEFAULT_POOL_SIZE;
069        try {
070            if (SystemProperties.isServerMode()) {
071                newPoolSize = Integer.parseInt(SystemProperties.get(
072                        Constants.SM_THREADPOOL_SIZE));
073            } else {
074                // For clients and CLIs, it is hardcoded to 3
075                newPoolSize = 2;
076            }
077        } catch (Exception e) {
078            newPoolSize = DEFAULT_POOL_SIZE;
079        }
080        if (newPoolSize == poolSize) {
081            // No change in the pool size, return
082            return;
083        } else {
084            poolSize = newPoolSize;
085        }
086        if (debug.messageEnabled()) {
087            debug.message("SMSThreadPool: poolSize=" + poolSize);
088        }
089        ShutdownManager shutdownMan = ShutdownManager.getInstance(); 
090        if (thrdPool != null) {
091            if (shutdownMan.acquireValidLock()) {
092                try {
093                    shutdownMan.removeShutdownListener(shutdownListener);
094                    thrdPool.shutdown();
095                    // Create a new thread pool
096                    thrdPool = new ThreadPool("smIdmThreadPool",
097                        poolSize, DEFAULT_TRESHOLD, false, debug);
098                    // Create the shutdown hook
099                    shutdownListener = new ShutdownListener() {
100                        public void shutdown() {
101                            thrdPool.shutdown();
102                        }
103                    };
104                    // Register to shutdown hook
105                    shutdownMan.addShutdownListener(shutdownListener);
106                } finally {
107                    shutdownMan.releaseLockAndNotify();
108                }
109            }
110        } else {
111            if (shutdownMan.acquireValidLock()) {
112                try {
113                    // Create a new thread pool
114                    thrdPool = new ThreadPool("smIdmThreadPool",
115                        poolSize, DEFAULT_TRESHOLD, false, debug);
116                    // Create the shutdown hook
117                    shutdownListener = new ShutdownListener() {
118                        public void shutdown() {
119                            thrdPool.shutdown();
120                        }
121                    };
122                    // Register to shutdown hook
123                    shutdownMan.addShutdownListener(shutdownListener);
124                } finally {
125                    shutdownMan.releaseLockAndNotify();
126                }
127            }
128        }
129        initialized = true;
130    }
131
132    /**
133     * Schdule a task for 
134     * <code>SMSThreadPool</code> to run.
135     *
136     * @param task 
137     *            task to be scheduled.
138     *
139     * @supported.api
140     */
141    public static boolean scheduleTask(Runnable task) {
142        boolean success = true;
143        if (!initialized) {
144            initialize(false); 
145        }
146        try {
147            thrdPool.run(task);
148        } catch (ThreadPoolException e) {
149            debug.error("SMSThreadPool: unable to schedule task" + e);
150            success = false;
151        }
152        return success;
153    }
154}