From 22e9e06b9d5f9dfe308d012bf23a6244b2562ae7 Mon Sep 17 00:00:00 2001 From: Jon Travis Date: Wed, 8 Jul 2009 14:54:51 -0700 Subject: [PATCH 1/3] (SIGAR-150) Wrapper class to synchronize Sigar method invocation Signed-off-by: Doug MacEachern --- .../java/src/org/hyperic/sigar/Humidor.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 bindings/java/src/org/hyperic/sigar/Humidor.java diff --git a/bindings/java/src/org/hyperic/sigar/Humidor.java b/bindings/java/src/org/hyperic/sigar/Humidor.java new file mode 100644 index 00000000..7dd80b14 --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/Humidor.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) [2004-2009], Hyperic, Inc. + * This file is part of SIGAR. + * + * SIGAR is free software; you can redistribute it and/or modify + * it under the terms version 2 of the GNU General Public License as + * published by the Free Software Foundation. This program is distributed + * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package org.hyperic.sigar; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * The Humidor provides access to a single Sigar instance. Sigar has a + * high-cost setup/teardown and has a high amount of caching, used to determine + * things like the % of CPU used in-between calls. + * + * The Humidor also synchronizes access to all Sigar methods, so all + * calls will be serialized. + */ +public class Humidor { + private static final Humidor INSTANCE = new Humidor(); + private Object LOCK = new Object(); + private InvocationHandler _handler; + private SigarProxy _sigar; + + private Humidor() {} + + private static class MyHandler implements InvocationHandler { + private SigarProxy _sigar; + private Object _lock = new Object(); + + public MyHandler(SigarProxy sigar) { + _sigar = sigar; + } + + public Object invoke(Object proxy, Method meth, Object[] args) + throws Throwable + { + try { + synchronized (_lock) { + return meth.invoke(_sigar, args); + } + } catch(InvocationTargetException e) { + throw e.getTargetException(); + } + } + } + + public SigarProxy getSigar() { + synchronized(LOCK) { + if (_sigar == null) { + Sigar s = new Sigar(); + _handler = new MyHandler(s); + _sigar = (SigarProxy) + Proxy.newProxyInstance(Humidor.class.getClassLoader(), + new Class[] { SigarProxy.class }, + _handler); + } + return _sigar; + } + } + + public static Humidor getInstance() { + return INSTANCE; + } +} From ce39c1ad1e949326f3507d03f16cac5822f19f4c Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 8 Jul 2009 15:28:49 -0700 Subject: [PATCH 2/3] support for caller constructed Sigar object --- bindings/java/src/org/hyperic/sigar/Humidor.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/Humidor.java b/bindings/java/src/org/hyperic/sigar/Humidor.java index 7dd80b14..c039bded 100644 --- a/bindings/java/src/org/hyperic/sigar/Humidor.java +++ b/bindings/java/src/org/hyperic/sigar/Humidor.java @@ -36,9 +36,14 @@ public class Humidor { private Object LOCK = new Object(); private InvocationHandler _handler; private SigarProxy _sigar; + private Sigar _impl; private Humidor() {} + public Humidor(Sigar sigar) { + _impl = sigar; + } + private static class MyHandler implements InvocationHandler { private SigarProxy _sigar; private Object _lock = new Object(); @@ -63,8 +68,10 @@ public class Humidor { public SigarProxy getSigar() { synchronized(LOCK) { if (_sigar == null) { - Sigar s = new Sigar(); - _handler = new MyHandler(s); + if (_impl == null) { + _impl = new Sigar(); + } + _handler = new MyHandler(_impl); _sigar = (SigarProxy) Proxy.newProxyInstance(Humidor.class.getClassLoader(), new Class[] { SigarProxy.class }, From 7d483e39820b3d296eecdb75028a97202511857e Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 8 Jul 2009 15:59:24 -0700 Subject: [PATCH 3/3] Humidor test --- .../hyperic/sigar/test/SigarTestRunner.java | 1 + .../org/hyperic/sigar/test/TestHumidor.java | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 bindings/java/src/org/hyperic/sigar/test/TestHumidor.java diff --git a/bindings/java/src/org/hyperic/sigar/test/SigarTestRunner.java b/bindings/java/src/org/hyperic/sigar/test/SigarTestRunner.java index 31615f08..332e099b 100644 --- a/bindings/java/src/org/hyperic/sigar/test/SigarTestRunner.java +++ b/bindings/java/src/org/hyperic/sigar/test/SigarTestRunner.java @@ -79,6 +79,7 @@ public class SigarTestRunner extends SigarCommandBase { TestUptime.class, TestVMware.class, TestWho.class, + TestHumidor.class }; private static final Class[] WIN32_TESTS = { diff --git a/bindings/java/src/org/hyperic/sigar/test/TestHumidor.java b/bindings/java/src/org/hyperic/sigar/test/TestHumidor.java new file mode 100644 index 00000000..1336908a --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/test/TestHumidor.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) [2004-2009], Hyperic, Inc. + * This file is part of SIGAR. + * + * SIGAR is free software; you can redistribute it and/or modify + * it under the terms version 2 of the GNU General Public License as + * published by the Free Software Foundation. This program is distributed + * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package org.hyperic.sigar.test; + +import java.util.ArrayList; + +import org.hyperic.sigar.CpuPerc; +import org.hyperic.sigar.Humidor; +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarProxy; + +public class TestHumidor extends SigarTestCase { + + public TestHumidor(String name) { + super(name); + } + + private static class HumidorThread extends Thread { + private SigarProxy sigar; + private HumidorThread(SigarProxy sigar) { + this.sigar = sigar; + } + + public void run() { + try { + getProcCpu(this.sigar); + } catch (Exception e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + } + + private static void getProcCpu(SigarProxy sigar) throws Exception { + long[] pids = sigar.getProcList(); + for (int j=0; j<10; j++) { + for (int i=0; i