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