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.shared.debug.Debug;
033
034import com.iplanet.am.util.SystemProperties;
035import com.iplanet.am.util.ThreadPool;
036import com.iplanet.am.util.ThreadPoolException;
037import org.forgerock.util.thread.listener.ShutdownListener;
038import org.forgerock.util.thread.listener.ShutdownManager;
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 = com.sun.identity.common.ShutdownManager.getInstance();
090        if (thrdPool != null) {
091            // Create a new thread pool
092            thrdPool = new ThreadPool("smIdmThreadPool",
093                poolSize, DEFAULT_TRESHOLD, false, debug);
094            // Create the shutdown hook
095            ShutdownListener newShutdownListener = new ShutdownListener() {
096                public void shutdown() {
097                    thrdPool.shutdown();
098                }
099            };
100            // Register to shutdown hook
101            shutdownMan.replaceShutdownListener(shutdownListener, newShutdownListener, null);
102        } else {
103
104            // Create a new thread pool
105            thrdPool = new ThreadPool("smIdmThreadPool",
106                poolSize, DEFAULT_TRESHOLD, false, debug);
107            // Create the shutdown hook
108            shutdownListener = new ShutdownListener() {
109                public void shutdown() {
110                    thrdPool.shutdown();
111                }
112            };
113            // Register to shutdown hook
114            shutdownMan.addShutdownListener(shutdownListener);
115
116        }
117        initialized = true;
118    }
119
120    /**
121     * Schdule a task for 
122     * <code>SMSThreadPool</code> to run.
123     *
124     * @param task 
125     *            task to be scheduled.
126     *
127     * @supported.api
128     */
129    public static boolean scheduleTask(Runnable task) {
130        boolean success = true;
131        if (!initialized) {
132            initialize(false); 
133        }
134        try {
135            thrdPool.run(task);
136        } catch (ThreadPoolException e) {
137            debug.error("SMSThreadPool: unable to schedule task" + e);
138            success = false;
139        }
140        return success;
141    }
142}