1 11 12 13 package com.sun.jmx.snmp.daemon; 14 15 16 import java.util.Vector ; 19 import java.util.Enumeration ; 20 import java.util.Hashtable ; 21 import java.util.Stack ; 22 import java.net.InetAddress ; 23 import java.net.SocketException ; 24 import java.io.InterruptedIOException ; 25 26 import com.sun.jmx.snmp.SnmpDefinitions; 29 import com.sun.jmx.snmp.SnmpStatusException; 30 import com.sun.jmx.snmp.SnmpVarBindList; 31 import com.sun.jmx.snmp.SnmpScopedPduRequest; 32 import com.sun.jmx.trace.Trace; 35 36 50 51 class SnmpSession implements SnmpDefinitions, Runnable { 52 53 56 59 protected transient SnmpAdaptorServer adaptor; 60 64 protected transient SnmpSocket informSocket = null; 65 68 private transient Hashtable informRequestList = new Hashtable (); 69 73 private transient Stack informRespq = new Stack (); 74 80 private transient Thread myThread = null; 81 85 private transient SnmpInformRequest syncInformReq ; 86 87 SnmpQManager snmpQman = null; 88 89 String dbgTag = "SnmpSession"; 90 91 private boolean isBeingCancelled = false; 92 93 96 101 public SnmpSession(SnmpAdaptorServer adp) throws SocketException { 102 adaptor = adp; 103 snmpQman = new SnmpQManager(); 104 SnmpResponseHandler snmpRespHdlr = new SnmpResponseHandler(adp, snmpQman); 105 initialize(adp, snmpRespHdlr); 106 } 107 110 public SnmpSession() throws SocketException { 111 } 112 119 protected synchronized void initialize(SnmpAdaptorServer adp, 120 SnmpResponseHandler snmpRespHdlr) 121 throws SocketException { 122 informSocket = new SnmpSocket(snmpRespHdlr, adp.getAddress(), adp.getBufferSize().intValue()); 123 124 myThread = new Thread (this, "SnmpSession"); 125 myThread.start(); 126 } 127 128 132 synchronized boolean isSessionActive() { 133 return ((adaptor.isActive()) && (myThread != null) && (myThread.isAlive())); 135 } 136 137 141 SnmpSocket getSocket() { 142 return informSocket; 143 } 144 145 149 SnmpQManager getSnmpQManager() { 150 return snmpQman; 151 } 152 153 157 private synchronized boolean syncInProgress() { 158 return syncInformReq != null ; 159 } 160 161 private synchronized void setSyncMode(SnmpInformRequest req) { 162 syncInformReq = req ; 163 } 164 165 private synchronized void resetSyncMode() { 166 if (syncInformReq == null) 167 return ; 168 syncInformReq = null ; 169 if (thisSessionContext()) 170 return ; 171 this.notifyAll() ; 172 } 173 174 181 boolean thisSessionContext() { 182 return (Thread.currentThread() == myThread) ; 183 } 184 185 194 SnmpInformRequest makeAsyncRequest(InetAddress addr, String cs, 195 SnmpInformHandler cb, 196 SnmpVarBindList vblst, int port) 197 throws SnmpStatusException { 198 199 if (!isSessionActive()) { 200 throw new SnmpStatusException("SNMP adaptor server not ONLINE"); 201 } 202 SnmpInformRequest snmpreq = new SnmpInformRequest(this, adaptor, addr, cs, port, cb); 203 snmpreq.start(vblst); 204 return snmpreq; 205 } 206 207 212 void waitForResponse(SnmpInformRequest req, long waitTime) { 213 214 if (! req.inProgress()) 215 return ; 216 setSyncMode(req) ; 217 218 if (isTraceOn()) { 219 trace("waitForResponse", "Session switching to sync mode for inform request " + req.getRequestId()); 220 } 221 long maxTime ; 222 if (waitTime <= 0) 223 maxTime = System.currentTimeMillis() + 6000 * 1000 ; 224 else 225 maxTime = System.currentTimeMillis() + waitTime ; 226 227 while (req.inProgress() || syncInProgress()) { 228 waitTime = maxTime - System.currentTimeMillis() ; 229 if (waitTime <= 0) 230 break ; 231 synchronized (this) { 232 if (! informRespq.removeElement(req)) { 233 try { 234 this.wait(waitTime) ; 235 } catch(InterruptedException e) { 236 } 237 continue ; 238 } 239 } 240 try { 241 processResponse(req) ; 242 } catch (Exception e) { 243 if (isDebugOn()) { 244 debug("waitForResponse", e); 245 } 246 } 247 } 248 resetSyncMode() ; 249 return ; 250 } 251 252 257 public void run() { 258 myThread = Thread.currentThread(); 259 myThread.setPriority(Thread.NORM_PRIORITY); 260 261 SnmpInformRequest reqc = null; 262 while (myThread != null) { 263 try { 264 reqc = nextResponse(); 265 if (reqc != null) { 266 processResponse(reqc); 267 } 268 } catch (ThreadDeath d) { 269 myThread = null; 270 if (isDebugOn()) { 271 debug("run", "Session thread unexpectedly shutting down"); 272 } 273 throw d ; 274 } 275 } 276 if (isTraceOn()) { 277 trace("run", "Session thread shutting down"); 278 } 279 myThread = null ; 280 } 281 282 private void processResponse(SnmpInformRequest reqc) { 283 284 while (reqc != null && myThread != null) { 285 try { 286 if (reqc != null) { 287 if (isTraceOn()) { 288 trace("processResponse", "Processing response to req = " + reqc.getRequestId()); 289 } 290 reqc.processResponse() ; reqc = null ; } 293 294 } catch (Exception e) { 295 if (isDebugOn()) { 296 debug("processResponse", e); 297 } 298 reqc = null ; 299 } catch (OutOfMemoryError ome) { 300 if (isDebugOn()) { 301 debug("processResponse", "Out of memory error in session thread"); 302 debug("processResponse", ome); 303 } 304 Thread.currentThread().yield(); 305 continue ; } 307 } 308 } 309 310 313 318 synchronized void addInformRequest(SnmpInformRequest snmpreq) throws SnmpStatusException { 319 320 if (!isSessionActive()) { 323 throw new SnmpStatusException("SNMP adaptor is not ONLINE or session is dead...") ; 324 } 325 informRequestList.put(snmpreq, snmpreq); 326 } 327 328 332 synchronized void removeInformRequest(SnmpInformRequest snmpreq) { 333 if(!isBeingCancelled) 336 informRequestList.remove(snmpreq) ; 337 338 if (syncInformReq != null && syncInformReq == snmpreq) { 339 resetSyncMode() ; 340 } 341 } 342 343 346 private void cancelAllRequests() { 347 final SnmpInformRequest[] list; 348 349 synchronized(this) { 350 351 if (informRequestList.isEmpty()) { 352 return ; 353 } 354 355 isBeingCancelled = true; 356 357 list = new SnmpInformRequest[informRequestList.size()]; 358 java.util.Iterator it = informRequestList.values().iterator(); 359 int i = 0; 360 while(it.hasNext()) { 361 SnmpInformRequest req = (SnmpInformRequest)it.next(); 362 list[i++] = req; 363 it.remove(); 364 } 365 informRequestList.clear(); 366 } 367 368 for(int i = 0; i < list.length; i++) 369 list[i].cancelRequest(); 370 } 371 372 378 void addResponse(SnmpInformRequest reqc) { 379 380 SnmpInformRequest snmpreq = (SnmpInformRequest) reqc ; 381 if (isSessionActive()) { 382 synchronized(this) { 383 informRespq.push(reqc) ; 384 this.notifyAll() ; 385 } 386 } else { 387 if (isDebugOn()) { 388 debug("addResponse", "Adaptor not ONLINE or session thread dead. So inform response is dropped..." + reqc.getRequestId()); 389 } 390 } 391 return ; 392 } 393 394 private synchronized SnmpInformRequest nextResponse() { 395 396 if (informRespq.isEmpty()) { 397 try { 398 if (isTraceOn()) { 399 trace("nextResponse", "Blocking for response"); 400 } 401 this.wait(); 402 } catch(InterruptedException e) { 403 } 404 } 405 if (informRespq.isEmpty()) 406 return null; 407 SnmpInformRequest reqc = (SnmpInformRequest) informRespq.firstElement(); 408 informRespq.removeElementAt(0) ; 409 return reqc ; 410 } 411 412 private synchronized void cancelAllResponses() { 413 if (informRespq != null) { 414 syncInformReq = null ; 415 informRespq.removeAllElements() ; 416 this.notifyAll() ; 417 } 418 } 419 420 424 final void destroySession() { 425 426 cancelAllRequests() ; 427 cancelAllResponses() ; 428 synchronized(this) { 429 informSocket.close() ; 430 informSocket = null ; 431 } 432 snmpQman.stopQThreads() ; 433 snmpQman = null ; 434 killSessionThread() ; 435 } 436 437 441 private synchronized void killSessionThread() { 442 443 if ((myThread != null) && (myThread.isAlive())) { 444 if (isTraceOn()) { 445 trace("killSessionThread", "Destroying session"); 446 } 447 if (!thisSessionContext()) { 448 myThread = null ; 449 this.notifyAll() ; 450 } else 451 myThread = null ; 452 } 453 } 454 455 462 public void finalize() { 463 464 if (informRespq != null) 465 informRespq.removeAllElements() ; 466 informRespq = null ; 467 if (informSocket != null) 468 informSocket.close() ; 469 informSocket = null ; 470 471 if (isTraceOn()) { 472 trace("finalize", "Shutting all servers"); 473 } 474 snmpQman = null ; 475 } 476 477 480 boolean isTraceOn() { 481 return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP); 482 } 483 484 void trace(String clz, String func, String info) { 485 Trace.send(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP, clz, func, info); 486 } 487 488 void trace(String func, String info) { 489 trace(dbgTag, func, info); 490 } 491 492 boolean isDebugOn() { 493 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP); 494 } 495 496 void debug(String clz, String func, String info) { 497 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, info); 498 } 499 500 void debug(String clz, String func, Throwable exception) { 501 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, exception); 502 } 503 504 void debug(String func, String info) { 505 debug(dbgTag, func, info); 506 } 507 508 void debug(String func, Throwable exception) { 509 debug(dbgTag, func, exception); 510 } 511 } 512 | Popular Tags |