Home | History | Annotate | Download | only in srm
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright (c) 2001 by Sun Microsystems, Inc.
     23  * All rights reserved.
     24  *
     25  * ResourceMonitor.java
     26  */
     27 
     28 
     29 package com.sun.wbem.solarisprovider.srm;
     30 
     31 import	java.util.HashSet;
     32 
     33 /**
     34  * Mediator between data model the native interface and the client.
     35  * Implements the singleton pattern.
     36  * @author Sun Microsystems, Inc.
     37  */
     38 public final class ResourceMonitor {
     39     /**
     40      * The UPDATETIME defines a time window in which a data request will
     41      *  be served from internal data cache instead of accessing rds, 5 sec.
     42      */
     43     private static final int UPDATETIME =  5000;
     44 
     45     /**
     46      * The RDSTIMEOUT defines the timeout after which the rds
     47      * rds will exit, if it hasn't received command from client, 30 sec.
     48      */
     49     private static final int RDSTIMEOUT =  30000;
     50     /**
     51      * The RDSINTERVAL defines a interval in which the rds
     52      * will update its data, 1 sec.
     53      */
     54     private static final int RDSINTERVAL =  1000;
     55 
     56     private static ResourceMonitor	rm;
     57     private static DataModel	dataModel;
     58     private long    lastUpdateTime;
     59     private int     updateTime	= UPDATETIME;
     60     private int     rdsTimeout	= RDSTIMEOUT;
     61     private int     rdsInterval = RDSINTERVAL;
     62 
     63     /**
     64      * threads that hold access into the data model
     65      */
     66     private int			    	activeClients;
     67 
     68     /**
     69      * Ensure that DataModel will be opened and closed once.
     70      */
     71     private boolean ifOpened = false;
     72 
     73     /**
     74      * Default constructor
     75      */
     76     private ResourceMonitor() {
     77     }
     78 
     79     /**
     80      * Should be used to obtain the singleton instance of this class
     81      * @return the singleton instance of this class
     82      */
     83     public static synchronized  ResourceMonitor getHandle() {
     84     	if (rm == null) {
     85             rm  = new ResourceMonitor();
     86      	    // The provider data model used by this monitor
     87             dataModel  = DataModel.getHandle(rm);
     88     	}
     89     	return rm;
     90     }
     91 
     92     /**
     93      * Open the data model used by this monitor with the following default
     94      * times, timeout after which the rds rds will exit 30 sec., interval in
     95      * which the rds will update its data 1 sec., time in which the data model
     96      * will refresh its cache 5 sec.
     97      */
     98     public synchronized void openDataModel() {
     99 	openDataModel(rdsTimeout, rdsInterval, updateTime);
    100     }
    101 
    102     /**
    103      * Open the data model used by this monitor.
    104      * @param rdsTimeout    timeout after which the rds rds will exit,
    105      *	    	    	    if -1 the default value 30 sec. will be used
    106      * @param rdsInterval   interval in which the rds will update its data
    107      *	    	    	    if -1 the default value 1 sec. will be used
    108      * @param updateTime    time in which the data model will refresh its cache
    109      *	    	    	    if -1 the default value 5 sec. will be used
    110      */
    111     public synchronized void openDataModel(int rdsTimeout,
    112 	    int rdsInterval, int updateTime) {
    113 
    114 	if (ifOpened == false) {
    115 	    if (updateTime != -1)
    116     	    	this.updateTime = updateTime;
    117 	    if (rdsTimeout != -1)
    118 	    	this.rdsTimeout = rdsTimeout;
    119 	    if (rdsTimeout != -1)
    120 	    	this.rdsInterval = rdsInterval;
    121 	    dataModel.open(rdsTimeout, rdsInterval);
    122 	    ifOpened = true;
    123 	}
    124 
    125     } // end openDataModel
    126 
    127     /**
    128      * Close the data model used by this monitor.
    129      */
    130     public synchronized void closeDataModel() {
    131 
    132 	if (ifOpened == true) {
    133 	    dataModel.close();
    134 	    ifOpened = false;
    135 	}
    136 
    137     } // end closeDataModel
    138 
    139     /**
    140      * Get the access to the data model. The caller should invoke
    141      * releaseDataModel() in order to allow the refresh of the data
    142      * model cache after it has finished the data processing.
    143      * @return the data model
    144      * @throws com.sun.wbem.solarisprovider.srm.SRMException
    145      *		if the data model couldn't be updated.
    146      */
    147     public synchronized
    148     DataModel getDataModel(boolean forceUpdate)
    149     throws SRMException {
    150 
    151 	if (ifOpened == false)
    152 	    throw new SRMException("Resource Data Model is not opened");
    153 
    154 	if (forceUpdate == true) {
    155 	    update();
    156 	} else {
    157 	    long currentTime = System.currentTimeMillis();
    158 	    if ((currentTime - lastUpdateTime) > updateTime) {
    159 		lastUpdateTime = currentTime;
    160 		update();
    161 	    }
    162 	}
    163 	activeClients++;
    164     	SRMDebug.trace(SRMDebug.THREAD_SYNC, "srm data cache update locked by "
    165 	    	+ activeClients + " clients");
    166 	return dataModel;
    167 
    168     } // end getDataModel
    169 
    170     /**
    171      * Release the lock into the data model. This allows the refresh of the
    172      * data model cache.
    173      * @param dm the data got from getDataModel() model must not be zero
    174      */
    175     public synchronized DataModel releaseDataModel(DataModel dm) {
    176 
    177     	if (dm != null) {
    178     	    activeClients--;
    179     	    SRMDebug.trace(SRMDebug.THREAD_SYNC,
    180 	    	    "srm data cache update locked by "
    181 		    + activeClients + " clients");
    182     	    notifyAll();
    183 	}
    184 	return null;
    185     } // end releaseDataModel
    186 
    187     /**
    188      * Wait till all data model readers release their lock, then do the update
    189      */
    190     private void update() throws SRMException {
    191 
    192     	    beforeUpdate();
    193 	    SRMDebug.trace(SRMDebug.THREAD_SYNC,
    194 	    	"starting srm data cache update, at: "
    195 	    	+System.currentTimeMillis()+"ms");
    196 	    dataModel.update();
    197 	    SRMDebug.trace(SRMDebug.THREAD_SYNC,
    198 	    	"finished srm data cache update, at: "
    199 	    	+System.currentTimeMillis()+"ms");
    200     }
    201 
    202     private static final int WAITTIME =  500;
    203 
    204     /**
    205      * Wait till all data model readers release their lock. To ensure
    206      * liveness only wait max. 10 * WAITTIME;
    207      */
    208     private synchronized void beforeUpdate() {
    209     	int tries = 10;
    210 
    211 	while (activeClients > 0) {
    212 	    try {
    213 	    	--tries;
    214 	    	wait(WAITTIME);
    215 		if (tries == 0)
    216 		    activeClients = 0;
    217 	    } catch (InterruptedException ex) {
    218 	    }
    219     	}
    220     }
    221 
    222 } // end class ResourceMonitor
    223