Skip to content

Commit

Permalink
Synchronize access to KstatCtl variable (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbwiddis authored May 30, 2018
1 parent 3ae3a6b commit 30d5819
Showing 1 changed file with 33 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@
public class KstatUtil {
private static final Logger LOG = LoggerFactory.getLogger(KstatUtil.class);

private static KstatCtl kc = LibKstat.INSTANCE.kstat_open();
// All active use of this variable must be synchronized
private static final KstatCtl kc = LibKstat.INSTANCE.kstat_open();

static {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LibKstat.INSTANCE.kstat_close(kc);
synchronized (kc) {
LibKstat.INSTANCE.kstat_close(kc);
}
}
});
}
Expand Down Expand Up @@ -154,13 +157,15 @@ public static long kstatDataLookupLong(Kstat ksp, String name) {
*/
public static boolean kstatRead(Kstat ksp) {
int retry = 0;
while (0 > LibKstat.INSTANCE.kstat_read(kc, ksp, null)) {
if (LibKstat.EAGAIN != Native.getLastError() || 5 <= ++retry) {
LOG.error("Failed to read kstat {}:{}:{}", new String(ksp.ks_module).trim(), ksp.ks_instance,
new String(ksp.ks_name).trim());
return false;
synchronized (kc) {
while (0 > LibKstat.INSTANCE.kstat_read(kc, ksp, null)) {
if (LibKstat.EAGAIN != Native.getLastError() || 5 <= ++retry) {
LOG.error("Failed to read kstat {}:{}:{}", new String(ksp.ks_module).trim(), ksp.ks_instance,
new String(ksp.ks_name).trim());
return false;
}
Util.sleep(8 << retry);
}
Util.sleep(8 << retry);
}
return true;
}
Expand All @@ -182,12 +187,14 @@ public static boolean kstatRead(Kstat ksp) {
* null
*/
public static Kstat kstatLookup(String module, int instance, String name) {
int ret = LibKstat.INSTANCE.kstat_chain_update(kc);
if (ret < 0) {
LOG.error("Failed to update kstat chain");
return null;
synchronized (kc) {
int ret = LibKstat.INSTANCE.kstat_chain_update(kc);
if (ret < 0) {
LOG.error("Failed to update kstat chain");
return null;
}
return LibKstat.INSTANCE.kstat_lookup(kc, module, instance, name);
}
return LibKstat.INSTANCE.kstat_lookup(kc, module, instance, name);
}

/**
Expand All @@ -208,16 +215,19 @@ public static Kstat kstatLookup(String module, int instance, String name) {
*/
public static List<Kstat> kstatLookupAll(String module, int instance, String name) {
List<Kstat> kstats = new ArrayList<>();
int ret = LibKstat.INSTANCE.kstat_chain_update(kc);
if (ret < 0) {
LOG.error("Failed to update kstat chain");
return kstats;
}
for (Kstat ksp = LibKstat.INSTANCE.kstat_lookup(kc, module, instance, name); ksp != null; ksp = ksp.next()) {
if ((module == null || module.equals(new String(ksp.ks_module).trim()))
&& (instance < 0 || instance == ksp.ks_instance)
&& (name == null || name.equals(new String(ksp.ks_name).trim()))) {
kstats.add(ksp);
synchronized (kc) {
int ret = LibKstat.INSTANCE.kstat_chain_update(kc);
if (ret < 0) {
LOG.error("Failed to update kstat chain");
return kstats;
}
for (Kstat ksp = LibKstat.INSTANCE.kstat_lookup(kc, module, instance, name); ksp != null; ksp = ksp
.next()) {
if ((module == null || module.equals(new String(ksp.ks_module).trim()))
&& (instance < 0 || instance == ksp.ks_instance)
&& (name == null || name.equals(new String(ksp.ks_name).trim()))) {
kstats.add(ksp);
}
}
}
return kstats;
Expand Down

0 comments on commit 30d5819

Please sign in to comment.