summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2007-02-07 11:08:26 +0000
committerBenoit Foucher <benoit@zeroc.com>2007-02-07 11:08:26 +0000
commit34012c94436f64d0aab9e5ff06024a557d1f746b (patch)
tree83db3b38ab28f2da73b071b00458790f8e7cf820 /cpp/src
parenthttp://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1739 (diff)
downloadice-34012c94436f64d0aab9e5ff06024a557d1f746b.tar.bz2
ice-34012c94436f64d0aab9e5ff06024a557d1f746b.tar.xz
ice-34012c94436f64d0aab9e5ff06024a557d1f746b.zip
Fixed bug 1767
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IceGrid/IceGridNode.cpp10
-rw-r--r--cpp/src/IceGrid/PlatformInfo.cpp166
-rw-r--r--cpp/src/IceGrid/PlatformInfo.h20
3 files changed, 126 insertions, 70 deletions
diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp
index 3f38c508056..adc97262422 100644
--- a/cpp/src/IceGrid/IceGridNode.cpp
+++ b/cpp/src/IceGrid/IceGridNode.cpp
@@ -469,6 +469,11 @@ NodeService::start(int argc, char* argv[])
_adapter->add(_node, nodeProxy->ice_getIdentity());
//
+ // Start the platform info thread if needed.
+ //
+ _node->getPlatformInfo().start();
+
+ //
// Create the node sessions with the registries.
//
_sessions.create(_node);
@@ -689,6 +694,11 @@ NodeService::stop()
_sessions.destroy();
//
+ // Stop the platform info thread.
+ //
+ _node->getPlatformInfo().stop();
+
+ //
// Break cylic reference counts.
//
_node->destroy();
diff --git a/cpp/src/IceGrid/PlatformInfo.cpp b/cpp/src/IceGrid/PlatformInfo.cpp
index a407c082d95..ff2aaf73537 100644
--- a/cpp/src/IceGrid/PlatformInfo.cpp
+++ b/cpp/src/IceGrid/PlatformInfo.cpp
@@ -64,6 +64,25 @@ getLocalizedPerfName(const Ice::LoggerPtr& logger, int idx)
}
return string(&localized[0]);
}
+
+class UpdateUtilizationAverageThread : public IceUtil::Thread
+{
+public:
+
+ UpdateUtilizationAverageThread(PlatformInfo& platform) : _platform(platform)
+ {
+ }
+
+ virtual void
+ run()
+ {
+ _platform.runUpdateLoadInfo();
+ }
+
+private:
+
+ PlatformInfo& _platform;
+};
#endif
}
@@ -106,18 +125,7 @@ PlatformInfo::PlatformInfo(const string& prefix,
// Initialization of the necessary data structures to get the load average.
//
#if defined(_WIN32)
- //
- // The performance counter query is lazy initialized. We can't
- // initialize it in the constructor because it might be called
- // when IceGrid is started on boot as a Windows service with the
- // Windows service control manager (SCM) locked. The query
- // initialization would fail (hang) because it requires to start
- // the "WMI Windows Adapter" service (which can't be started
- // because the SCM is locked...).
- //
- _initQuery = false;
- _query = NULL;
- _counter = NULL;
+ _terminated = false;
_usages1.insert(_usages1.end(), 1 * 60 / 5, 0); // 1 sample every 5 seconds during 1 minutes.
_usages5.insert(_usages5.end(), 5 * 60 / 5, 0); // 1 sample every 5 seconds during 5 minutes.
_usages15.insert(_usages15.end(), 15 * 60 / 5, 0); // 1 sample every 5 seconds during 15 minutes.
@@ -288,12 +296,7 @@ PlatformInfo::PlatformInfo(const string& prefix,
PlatformInfo::~PlatformInfo()
{
-#ifdef _WIN32
- if(_query != NULL)
- {
- PdhCloseQuery(_query);
- }
-#elif defined(_AIX)
+#if defined(_AIX)
if(_kmem > 0)
{
close(_kmem);
@@ -301,6 +304,31 @@ PlatformInfo::~PlatformInfo()
#endif
}
+void
+PlatformInfo::start()
+{
+#if defined(_WIN32)
+ _updateUtilizationThread = new UpdateUtilizationAverageThread(*this);
+ _updateUtilizationThread->start();
+#endif
+}
+
+void
+PlatformInfo::stop()
+{
+#if defined(_WIN32)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_utilizationMonitor);
+ _terminated = true;
+ _utilizationMonitor.notify();
+ }
+
+ assert(_updateUtilizationThread);
+ _updateUtilizationThread->getThreadControl().join();
+ _updateUtilizationThread = 0;
+#endif
+}
+
NodeInfo
PlatformInfo::getNodeInfo() const
{
@@ -346,42 +374,7 @@ PlatformInfo::getLoadInfo()
info.avg15 = -1.0f;
#if defined(_WIN32)
- int usage = 100;
- // If we haven't yet initialized the query system do so.
- if(!_initQuery)
- {
- initQuery();
- }
- if(_query != NULL && _counter != NULL)
- {
- PDH_STATUS err = PdhCollectQueryData(_query);
- if(err == ERROR_SUCCESS)
- {
- DWORD type;
- PDH_FMT_COUNTERVALUE value;
- PdhGetFormattedCounterValue(_counter, PDH_FMT_LONG, &type, &value);
- usage = static_cast<int>(value.longValue);
- }
- else
- {
- Ice::SyscallException ex(__FILE__, __LINE__);
- ex.error = err;
- Ice::Warning out(_traceLevels->logger);
- out << "PdhCollectQueryData failed: " << ex;
- }
- }
-
- _last1Total += usage - _usages1.back();
- _last5Total += usage - _usages5.back();
- _last15Total += usage - _usages15.back();
-
- _usages1.pop_back();
- _usages5.pop_back();
- _usages15.pop_back();
- _usages1.push_front(usage);
- _usages5.push_front(usage);
- _usages15.push_front(usage);
-
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_utilizationMonitor);
info.avg1 = static_cast<float>(_last1Total) / _usages1.size() / 100.0f;
info.avg5 = static_cast<float>(_last5Total) / _usages5.size() / 100.0f;
info.avg15 = static_cast<float>(_last15Total) / _usages15.size() / 100.0f;
@@ -447,15 +440,23 @@ PlatformInfo::getCwd() const
#ifdef _WIN32
void
-PlatformInfo::initQuery()
+PlatformInfo::runUpdateLoadInfo()
{
- // We only want to try to initialize the query subsystem once.
- _initQuery = true;
+ //
+ // NOTE: We shouldn't initialize the performance counter from the
+ // PlatformInfo constructor because it might be called when
+ // IceGrid is started on boot as a Windows service with the
+ // Windows service control manager (SCM) locked. The query
+ // initialization would fail (hang) because it requires to start
+ // the "WMI Windows Adapter" service (which can't be started
+ // because the SCM is locked...).
+ //
//
// Open the query.
//
- PDH_STATUS err = PdhOpenQuery(0, 0, &_query);
+ HQUERY query;
+ PDH_STATUS err = PdhOpenQuery(0, 0, &query);
if(err != ERROR_SUCCESS)
{
Ice::SyscallException ex(__FILE__, __LINE__);
@@ -477,13 +478,13 @@ PlatformInfo::initQuery()
string percentProcessorTime = getLocalizedPerfName(_traceLevels->logger, 6);
if(processor.empty() || percentProcessorTime.empty())
{
- PdhCloseQuery(_query);
- _query = NULL;
+ PdhCloseQuery(query);
return;
}
const string name = "\\" + processor + "(_Total)\\" + percentProcessorTime;
- err = PdhAddCounter(_query, name.c_str(), 0, &_counter);
+ HCOUNTER _counter;
+ err = PdhAddCounter(query, name.c_str(), 0, &_counter);
if(err != ERROR_SUCCESS)
{
Ice::SyscallException ex(__FILE__, __LINE__);
@@ -491,9 +492,48 @@ PlatformInfo::initQuery()
Ice::Warning out(_traceLevels->logger);
out << "can't add performance counter `" << name << "':\n" << ex;
- PdhCloseQuery(_query);
- _query = NULL;
+ PdhCloseQuery(query);
return;
}
+
+ while(true)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_utilizationMonitor);
+ _utilizationMonitor.timedWait(IceUtil::Time::seconds(5)); // 5 seconds.
+ if(_terminated)
+ {
+ break;
+ }
+
+ int usage = 100;
+ PDH_STATUS err = PdhCollectQueryData(query);
+ if(err == ERROR_SUCCESS)
+ {
+ DWORD type;
+ PDH_FMT_COUNTERVALUE value;
+ PdhGetFormattedCounterValue(_counter, PDH_FMT_LONG, &type, &value);
+ usage = static_cast<int>(value.longValue);
+ }
+ else
+ {
+ Ice::SyscallException ex(__FILE__, __LINE__);
+ ex.error = err;
+ Ice::Warning out(_traceLevels->logger);
+ out << "PdhCollectQueryData failed: " << ex;
+ }
+
+ _last1Total += usage - _usages1.back();
+ _last5Total += usage - _usages5.back();
+ _last15Total += usage - _usages15.back();
+
+ _usages1.pop_back();
+ _usages5.pop_back();
+ _usages15.pop_back();
+ _usages1.push_front(usage);
+ _usages5.push_front(usage);
+ _usages15.push_front(usage);
+ }
+
+ PdhCloseQuery(query);
}
#endif
diff --git a/cpp/src/IceGrid/PlatformInfo.h b/cpp/src/IceGrid/PlatformInfo.h
index 1447cdd3cc1..6237e98d7de 100644
--- a/cpp/src/IceGrid/PlatformInfo.h
+++ b/cpp/src/IceGrid/PlatformInfo.h
@@ -10,6 +10,7 @@
#ifndef ICE_GRID_PLATFORM_INFO_H
#define ICE_GRID_PLATFORM_INFO_H
+#include <IceUtil/Thread.h>
#include <IceGrid/Internal.h>
#ifdef _WIN32
@@ -17,6 +18,8 @@
# include <deque>
#endif
+
+
namespace IceGrid
{
@@ -33,6 +36,9 @@ public:
PlatformInfo(const std::string&, const Ice::CommunicatorPtr&, const TraceLevelsPtr&);
~PlatformInfo();
+ void start();
+ void stop();
+
InternalNodeInfoPtr getInternalNodeInfo() const;
InternalReplicaInfoPtr getInternalReplicaInfo() const;
@@ -44,11 +50,11 @@ public:
std::string getDataDir() const;
std::string getCwd() const;
-private:
-
#if defined(_WIN32)
- void initQuery();
-#endif
+ void runUpdateLoadInfo();
+#endif
+
+private:
const TraceLevelsPtr _traceLevels;
std::string _name;
@@ -63,9 +69,9 @@ private:
std::string _endpoints;
#if defined(_WIN32)
- bool _initQuery;
- HQUERY _query;
- HCOUNTER _counter;
+ IceUtil::ThreadPtr _updateUtilizationThread;
+ IceUtil::Monitor<IceUtil::Mutex> _utilizationMonitor;
+ bool _terminated;
std::deque<int> _usages1;
std::deque<int> _usages5;
std::deque<int> _usages15;