1. /*
  2. * @(#)file SnmpSendServer.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 1.6
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.daemon;
  12. import java.util.Enumeration;
  13. import java.util.Vector;
  14. // import debug stuff
  15. //
  16. import com.sun.jmx.trace.Trace;
  17. /**
  18. * This class starts a thread which picks up a session from the queue
  19. * and prepares the inform request protocol data unit (PDU) packet and sends
  20. * it to the manager. The request is then added to the wait queue and
  21. * marked as one that is waiting for a response.
  22. */
  23. final class SnmpSendServer extends Thread {
  24. // VARIABLES
  25. //----------
  26. private int intervalRange = 5 * 1000 ;
  27. private Vector readyPool ;
  28. SnmpQManager snmpq = null ;
  29. String dbgTag = "SnmpSendServer";
  30. // This boolean is used to stop handling requests while the corresponding SnmpQManager
  31. // is being destroyed.
  32. //
  33. boolean isBeingDestroyed = false;
  34. // CONSTRUCTORS
  35. //-------------
  36. public SnmpSendServer(ThreadGroup grp, SnmpQManager q) {
  37. super(grp, "SnmpSendServer") ;
  38. snmpq = q ;
  39. start() ;
  40. }
  41. public synchronized void stopSendServer() {
  42. if (isAlive()) {
  43. interrupt();
  44. try {
  45. // Wait until the thread die.
  46. //
  47. join();
  48. } catch (InterruptedException e) {
  49. // Ignore...
  50. }
  51. }
  52. }
  53. public void run () {
  54. Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
  55. if (isTraceOn()) {
  56. trace("run", "Thread Started");
  57. }
  58. while (true) {
  59. try {
  60. prepareAndSendRequest() ;
  61. if (isBeingDestroyed == true)
  62. break;
  63. } catch (Exception anye) {
  64. if (isDebugOn()) {
  65. debug("run", "Exception in send server");
  66. debug("run", anye);
  67. }
  68. } catch (ThreadDeath td) {
  69. // This is not good but Netscape does kill all threads when
  70. // the pagecontext changes.
  71. if (isDebugOn()) {
  72. debug("run", "Exiting... Fatal error");
  73. }
  74. throw td ;
  75. } catch (OutOfMemoryError ome) {
  76. if (isDebugOn()) {
  77. debug("run", "Out of memory");
  78. }
  79. } catch (Error err) {
  80. if (isDebugOn()) {
  81. debug("run", err);
  82. }
  83. throw err ;
  84. }
  85. }
  86. }
  87. private void prepareAndSendRequest() {
  88. if (readyPool == null || readyPool.isEmpty()) {
  89. // wait to be signaled by the an active request.
  90. if (isTraceOn()) {
  91. trace("prepareAndSendRequest", "Blocking for inform requests");
  92. }
  93. readyPool = snmpq.getAllOutstandingRequest(intervalRange) ;
  94. if (isBeingDestroyed == true)
  95. return;
  96. } else {
  97. if (isDebugOn()) {
  98. debug("prepareAndSendRequest", "Inform requests from a previous block left unprocessed. Will try again");
  99. }
  100. }
  101. if (isTraceOn()) {
  102. trace("prepareAndSendRequest", "List of inform requests to send : " + reqListToString(readyPool));
  103. }
  104. synchronized(this) {
  105. if (readyPool.size() < 2) {
  106. // Fire all requests as independent requests.
  107. fireRequestList(readyPool) ;
  108. return ;
  109. }
  110. while (!readyPool.isEmpty()) {
  111. SnmpInformRequest req = (SnmpInformRequest) readyPool.lastElement() ;
  112. if (req != null && req.inProgress()) {
  113. fireRequest(req) ;
  114. }
  115. readyPool.removeElementAt(readyPool.size() - 1) ;
  116. }
  117. readyPool.removeAllElements() ;
  118. }
  119. }
  120. /**
  121. * This will fire the specified request.
  122. */
  123. void fireRequest(SnmpInformRequest req) {
  124. if (req != null && req.inProgress()) {
  125. if (isTraceOn()) {
  126. trace("fireRequest", "Firing inform request directly. -> " + req.getRequestId());
  127. }
  128. req.action() ;
  129. }
  130. }
  131. void fireRequestList(Vector reqList) {
  132. // Fire all requests as independent requests.
  133. while (!reqList.isEmpty()) {
  134. SnmpInformRequest req = (SnmpInformRequest) reqList.lastElement() ;
  135. if (req != null && req.inProgress())
  136. fireRequest(req) ;
  137. reqList.removeElementAt(reqList.size() - 1) ;
  138. }
  139. }
  140. final String reqListToString(Vector vec) {
  141. StringBuffer s = new StringBuffer(vec.size() * 100) ;
  142. Enumeration dbge = vec.elements() ;
  143. while (dbge.hasMoreElements()) {
  144. SnmpInformRequest reqc = (SnmpInformRequest) dbge.nextElement() ;
  145. s.append("InformRequestId -> ") ;
  146. s.append(reqc.getRequestId()) ;
  147. s.append(" / Destination -> ") ;
  148. s.append(reqc.getAddress()) ;
  149. s.append(". ") ;
  150. }
  151. String str = s.toString() ;
  152. s = null ;
  153. return str ;
  154. }
  155. // TRACES & DEBUG
  156. //---------------
  157. boolean isTraceOn() {
  158. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP);
  159. }
  160. void trace(String clz, String func, String info) {
  161. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
  162. }
  163. void trace(String func, String info) {
  164. trace(dbgTag, func, info);
  165. }
  166. boolean isDebugOn() {
  167. return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
  168. }
  169. void debug(String clz, String func, String info) {
  170. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
  171. }
  172. void debug(String clz, String func, Throwable exception) {
  173. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, exception);
  174. }
  175. void debug(String func, String info) {
  176. debug(dbgTag, func, info);
  177. }
  178. void debug(String func, Throwable exception) {
  179. debug(dbgTag, func, exception);
  180. }
  181. }