src/share/vm/services/diagnosticFramework.cpp

changeset 5047
31a4e55f8c9d
parent 3905
5a1f452f8f90
child 6680
78bbf4d43a14
     1.1 --- a/src/share/vm/services/diagnosticFramework.cpp	Wed May 01 09:00:39 2013 -0700
     1.2 +++ b/src/share/vm/services/diagnosticFramework.cpp	Fri May 03 05:05:31 2013 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -359,7 +359,7 @@
    1.11    while (arg != NULL) {
    1.12      array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
    1.13                    arg->type(), arg->default_string(), arg->is_mandatory(),
    1.14 -                  false, idx));
    1.15 +                  false, arg->allow_multiple(), idx));
    1.16      idx++;
    1.17      arg = arg->next();
    1.18    }
    1.19 @@ -367,32 +367,42 @@
    1.20    while (arg != NULL) {
    1.21      array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
    1.22                    arg->type(), arg->default_string(), arg->is_mandatory(),
    1.23 -                  true));
    1.24 +                  true, arg->allow_multiple()));
    1.25      arg = arg->next();
    1.26    }
    1.27    return array;
    1.28  }
    1.29  
    1.30  DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL;
    1.31 +bool DCmdFactory::_has_pending_jmx_notification = false;
    1.32  
    1.33 -void DCmd::parse_and_execute(outputStream* out, const char* cmdline,
    1.34 -                             char delim, TRAPS) {
    1.35 +void DCmd::parse_and_execute(DCmdSource source, outputStream* out,
    1.36 +                             const char* cmdline, char delim, TRAPS) {
    1.37  
    1.38    if (cmdline == NULL) return; // Nothing to do!
    1.39    DCmdIter iter(cmdline, '\n');
    1.40  
    1.41 +  int count = 0;
    1.42    while (iter.has_next()) {
    1.43 +    if(source == DCmd_Source_MBean && count > 0) {
    1.44 +      // When diagnostic commands are invoked via JMX, each command line
    1.45 +      // must contains one and only one command because of the Permission
    1.46 +      // checks performed by the DiagnosticCommandMBean
    1.47 +      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
    1.48 +              "Invalid syntax");
    1.49 +    }
    1.50      CmdLine line = iter.next();
    1.51      if (line.is_stop()) {
    1.52        break;
    1.53      }
    1.54      if (line.is_executable()) {
    1.55 -      DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK);
    1.56 +      DCmd* command = DCmdFactory::create_local_DCmd(source, line, out, CHECK);
    1.57        assert(command != NULL, "command error must be handled before this line");
    1.58        DCmdMark mark(command);
    1.59        command->parse(&line, delim, CHECK);
    1.60 -      command->execute(CHECK);
    1.61 +      command->execute(source, CHECK);
    1.62      }
    1.63 +    count++;
    1.64    }
    1.65  }
    1.66  
    1.67 @@ -420,15 +430,78 @@
    1.68    return _dcmdparser.argument_info_array();
    1.69  }
    1.70  
    1.71 +void DCmdFactory::push_jmx_notification_request() {
    1.72 +  MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    1.73 +  _has_pending_jmx_notification = true;
    1.74 +  Service_lock->notify_all();
    1.75 +}
    1.76 +
    1.77 +void DCmdFactory::send_notification(TRAPS) {
    1.78 +  DCmdFactory::send_notification_internal(THREAD);
    1.79 +  // Clearing pending exception to avoid premature termination of
    1.80 +  // the service thread
    1.81 +  if (HAS_PENDING_EXCEPTION) {
    1.82 +    CLEAR_PENDING_EXCEPTION;
    1.83 +  }
    1.84 +}
    1.85 +void DCmdFactory::send_notification_internal(TRAPS) {
    1.86 +  ResourceMark rm(THREAD);
    1.87 +  HandleMark hm(THREAD);
    1.88 +  bool notif = false;
    1.89 +  {
    1.90 +    MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    1.91 +    notif = _has_pending_jmx_notification;
    1.92 +    _has_pending_jmx_notification = false;
    1.93 +  }
    1.94 +  if (notif) {
    1.95 +
    1.96 +    Klass* k = Management::sun_management_ManagementFactoryHelper_klass(CHECK);
    1.97 +    instanceKlassHandle mgmt_factory_helper_klass(THREAD, k);
    1.98 +
    1.99 +    JavaValue result(T_OBJECT);
   1.100 +    JavaCalls::call_static(&result,
   1.101 +            mgmt_factory_helper_klass,
   1.102 +            vmSymbols::getDiagnosticCommandMBean_name(),
   1.103 +            vmSymbols::getDiagnosticCommandMBean_signature(),
   1.104 +            CHECK);
   1.105 +
   1.106 +    instanceOop m = (instanceOop) result.get_jobject();
   1.107 +    instanceHandle dcmd_mbean_h(THREAD, m);
   1.108 +
   1.109 +    Klass* k2 = Management::sun_management_DiagnosticCommandImpl_klass(CHECK);
   1.110 +    instanceKlassHandle dcmd_mbean_klass(THREAD, k2);
   1.111 +
   1.112 +    if (!dcmd_mbean_h->is_a(k2)) {
   1.113 +      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.114 +              "ManagementFactory.getDiagnosticCommandMBean didn't return a DiagnosticCommandMBean instance");
   1.115 +    }
   1.116 +
   1.117 +    JavaValue result2(T_VOID);
   1.118 +    JavaCallArguments args2(dcmd_mbean_h);
   1.119 +
   1.120 +    JavaCalls::call_virtual(&result2,
   1.121 +            dcmd_mbean_klass,
   1.122 +            vmSymbols::createDiagnosticFrameworkNotification_name(),
   1.123 +            vmSymbols::void_method_signature(),
   1.124 +            &args2,
   1.125 +            CHECK);
   1.126 +  }
   1.127 +}
   1.128 +
   1.129  Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
   1.130 +bool DCmdFactory::_send_jmx_notification = false;
   1.131  
   1.132 -DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
   1.133 +DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) {
   1.134    MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
   1.135    DCmdFactory* factory = _DCmdFactoryList;
   1.136    while (factory != NULL) {
   1.137      if (strlen(factory->name()) == len &&
   1.138          strncmp(name, factory->name(), len) == 0) {
   1.139 -      return factory;
   1.140 +      if(factory->export_flags() & source) {
   1.141 +        return factory;
   1.142 +      } else {
   1.143 +        return NULL;
   1.144 +      }
   1.145      }
   1.146      factory = factory->_next;
   1.147    }
   1.148 @@ -439,11 +512,16 @@
   1.149    MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
   1.150    factory->_next = _DCmdFactoryList;
   1.151    _DCmdFactoryList = factory;
   1.152 +  if (_send_jmx_notification && !factory->_hidden
   1.153 +      && (factory->_export_flags & DCmd_Source_MBean)) {
   1.154 +    DCmdFactory::push_jmx_notification_request();
   1.155 +  }
   1.156    return 0; // Actually, there's no checks for duplicates
   1.157  }
   1.158  
   1.159 -DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) {
   1.160 -  DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());
   1.161 +DCmd* DCmdFactory::create_global_DCmd(DCmdSource source, CmdLine &line,
   1.162 +                                      outputStream* out, TRAPS) {
   1.163 +  DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
   1.164    if (f != NULL) {
   1.165      if (f->is_enabled()) {
   1.166        THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
   1.167 @@ -455,8 +533,9 @@
   1.168               "Unknown diagnostic command");
   1.169  }
   1.170  
   1.171 -DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) {
   1.172 -  DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());
   1.173 +DCmd* DCmdFactory::create_local_DCmd(DCmdSource source, CmdLine &line,
   1.174 +                                     outputStream* out, TRAPS) {
   1.175 +  DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
   1.176    if (f != NULL) {
   1.177      if (!f->is_enabled()) {
   1.178        THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
   1.179 @@ -468,12 +547,12 @@
   1.180               "Unknown diagnostic command");
   1.181  }
   1.182  
   1.183 -GrowableArray<const char*>* DCmdFactory::DCmd_list() {
   1.184 +GrowableArray<const char*>* DCmdFactory::DCmd_list(DCmdSource source) {
   1.185    MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
   1.186    GrowableArray<const char*>* array = new GrowableArray<const char*>();
   1.187    DCmdFactory* factory = _DCmdFactoryList;
   1.188    while (factory != NULL) {
   1.189 -    if (!factory->is_hidden()) {
   1.190 +    if (!factory->is_hidden() && (factory->export_flags() & source)) {
   1.191        array->append(factory->name());
   1.192      }
   1.193      factory = factory->next();
   1.194 @@ -481,15 +560,16 @@
   1.195    return array;
   1.196  }
   1.197  
   1.198 -GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() {
   1.199 +GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list(DCmdSource source ) {
   1.200    MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
   1.201    GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>();
   1.202    DCmdFactory* factory = _DCmdFactoryList;
   1.203    while (factory != NULL) {
   1.204 -    if (!factory->is_hidden()) {
   1.205 +    if (!factory->is_hidden() && (factory->export_flags() & source)) {
   1.206        array->append(new DCmdInfo(factory->name(),
   1.207                      factory->description(), factory->impact(),
   1.208 -                    factory->num_arguments(), factory->is_enabled()));
   1.209 +                    factory->permission(), factory->num_arguments(),
   1.210 +                    factory->is_enabled()));
   1.211      }
   1.212      factory = factory->next();
   1.213    }

mercurial