Improve testing on macOS by eliminating sigar logging

patch by mkjellman, reviewed by jasobrown for CASSANDRA-13233


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e3968cfd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e3968cfd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e3968cfd

Branch: refs/heads/cassandra-3.11
Commit: e3968cfd1e786f260029cf8cde4164719ae56c53
Parents: 244f887
Author: Michael Kjellman <kjell...@apple.com>
Authored: Thu Mar 2 14:03:25 2017 -0800
Committer: Jason Brown <jasedbr...@gmail.com>
Committed: Fri Mar 3 11:15:52 2017 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../org/apache/cassandra/utils/CLibrary.java    | 124 +++++++++++-------
 .../apache/cassandra/utils/CLibraryDarwin.java  | 131 +++++++++++++++++++
 .../apache/cassandra/utils/CLibraryLinux.java   | 131 +++++++++++++++++++
 .../apache/cassandra/utils/CLibraryWindows.java | 103 +++++++++++++++
 .../apache/cassandra/utils/CLibraryWrapper.java |  40 ++++++
 .../org/apache/cassandra/utils/HeapUtils.java   |   6 +-
 .../org/apache/cassandra/utils/UUIDGen.java     |   2 +-
 .../apache/cassandra/utils/CLibraryTest.java    |   8 ++
 9 files changed, 494 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 1c3869f..076b337 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.12
+ * Improve testing on macOS by eliminating sigar logging (CASSANDRA-13233)
  * Cqlsh copy-from should error out when csv contains invalid data for 
collections (CASSANDRA-13071)
  * Update c.yaml doc for offheap memtables (CASSANDRA-13179)
  * Faster StreamingHistogram (CASSANDRA-13038)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/CLibrary.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CLibrary.java 
b/src/java/org/apache/cassandra/utils/CLibrary.java
index 347b0df..71f4148 100644
--- a/src/java/org/apache/cassandra/utils/CLibrary.java
+++ b/src/java/org/apache/cassandra/utils/CLibrary.java
@@ -23,21 +23,33 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.nio.channels.FileChannel;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
 import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.sun.jna.LastErrorException;
-import com.sun.jna.Native;
-import com.sun.jna.Pointer;
+
+import static org.apache.cassandra.utils.CLibrary.OSType.LINUX;
+import static org.apache.cassandra.utils.CLibrary.OSType.MAC;
+import static org.apache.cassandra.utils.CLibrary.OSType.WINDOWS;
+import static org.apache.cassandra.utils.CLibrary.OSType.AIX;
 
 public final class CLibrary
 {
     private static final Logger logger = 
LoggerFactory.getLogger(CLibrary.class);
 
+    public enum OSType
+    {
+        LINUX,
+        MAC,
+        WINDOWS,
+        AIX,
+        OTHER;
+    }
+
+    private static final OSType osType;
+
     private static final int MCL_CURRENT;
     private static final int MCL_FUTURE;
 
@@ -56,39 +68,32 @@ public final class CLibrary
     private static final int POSIX_FADV_DONTNEED   = 4; /* fadvise.h */
     private static final int POSIX_FADV_NOREUSE    = 5; /* fadvise.h */
 
-    static boolean jnaAvailable = true;
-    static boolean jnaLockable = false;
+    private static final CLibraryWrapper wrappedCLibrary;
+    private static boolean jnaLockable = false;
 
     static
     {
-        try
-        {
-            Native.register("c");
-        }
-        catch (NoClassDefFoundError e)
-        {
-            logger.warn("JNA not found. Native methods will be disabled.");
-            jnaAvailable = false;
-        }
-        catch (UnsatisfiedLinkError e)
+        // detect the OS type the JVM is running on and then set the 
CLibraryWrapper
+        // instance to a compatable implementation of CLibraryWrapper for that 
OS type
+        osType = getOsType();
+        switch (osType)
         {
-            logger.warn("JNA link failure, one or more native method will be 
unavailable.");
-            logger.trace("JNA link failure details: {}", e.getMessage());
-        }
-        catch (NoSuchMethodError e)
-        {
-            logger.warn("Obsolete version of JNA present; unable to register C 
library. Upgrade to JNA 3.2.7 or later");
-            jnaAvailable = false;
+            case MAC: wrappedCLibrary = new CLibraryDarwin(); break;
+            case WINDOWS: wrappedCLibrary = new CLibraryWindows(); break;
+            case LINUX:
+            case AIX:
+            case OTHER:
+            default: wrappedCLibrary = new CLibraryLinux();
         }
 
         if (System.getProperty("os.arch").toLowerCase().contains("ppc"))
         {
-            if (System.getProperty("os.name").toLowerCase().contains("linux"))
+            if (osType == LINUX)
             {
                MCL_CURRENT = 0x2000;
                MCL_FUTURE = 0x4000;
             }
-            else if 
(System.getProperty("os.name").toLowerCase().contains("aix"))
+            else if (osType == AIX)
             {
                 MCL_CURRENT = 0x100;
                 MCL_FUTURE = 0x200;
@@ -106,14 +111,24 @@ public final class CLibrary
         }
     }
 
-    private static native int mlockall(int flags) throws LastErrorException;
-    private static native int munlockall() throws LastErrorException;
-    private static native int fcntl(int fd, int command, long flags) throws 
LastErrorException;
-    private static native int posix_fadvise(int fd, long offset, int len, int 
flag) throws LastErrorException;
-    private static native int open(String path, int flags) throws 
LastErrorException;
-    private static native int fsync(int fd) throws LastErrorException;
-    private static native int close(int fd) throws LastErrorException;
-    private static native Pointer strerror(int errnum) throws 
LastErrorException;
+    private CLibrary() {}
+
+    /**
+     * @return the detected OSType of the Operating System running the JVM 
using crude string matching
+     */
+    private static OSType getOsType()
+    {
+        String osName = System.getProperty("os.name").toLowerCase();
+        if (osName.contains("mac"))
+            return MAC;
+        else if (osName.contains("windows"))
+            return WINDOWS;
+        else if (osName.contains("aix"))
+            return AIX;
+        else
+            // fall back to the Linux impl for all unknown OS types until 
otherwise implicitly supported as needed
+            return LINUX;
+    }
 
     private static int errno(RuntimeException e)
     {
@@ -129,11 +144,9 @@ public final class CLibrary
         }
     }
 
-    private CLibrary() {}
-
     public static boolean jnaAvailable()
     {
-        return jnaAvailable;
+        return wrappedCLibrary.jnaAvailable();
     }
 
     public static boolean jnaMemoryLockable()
@@ -145,7 +158,7 @@ public final class CLibrary
     {
         try
         {
-            mlockall(MCL_CURRENT);
+            wrappedCLibrary.callMlockall(MCL_CURRENT);
             jnaLockable = true;
             logger.info("JNA mlockall successful");
         }
@@ -158,13 +171,13 @@ public final class CLibrary
             if (!(e instanceof LastErrorException))
                 throw e;
 
-            if (errno(e) == ENOMEM && 
System.getProperty("os.name").toLowerCase().contains("linux"))
+            if (errno(e) == ENOMEM && osType == LINUX)
             {
                 logger.warn("Unable to lock JVM memory (ENOMEM)."
                         + " This can result in part of the JVM being swapped 
out, especially with mmapped I/O enabled."
                         + " Increase RLIMIT_MEMLOCK or run Cassandra as 
root.");
             }
-            else if 
(!System.getProperty("os.name").toLowerCase().contains("mac"))
+            else if (osType != MAC)
             {
                 // OS X allows mlockall to be called, but always returns an 
error
                 logger.warn("Unknown mlockall error {}", errno(e));
@@ -209,16 +222,16 @@ public final class CLibrary
 
         try
         {
-            if (System.getProperty("os.name").toLowerCase().contains("linux"))
+            if (osType == LINUX)
             {
-                int result = posix_fadvise(fd, offset, len, 
POSIX_FADV_DONTNEED);
+                int result = wrappedCLibrary.callPosixFadvise(fd, offset, len, 
POSIX_FADV_DONTNEED);
                 if (result != 0)
                     NoSpamLogger.log(
                             logger,
                             NoSpamLogger.Level.WARN,
                             10,
                             TimeUnit.MINUTES,
-                            "Failed trySkipCache on file: {} Error: " + 
strerror(result).getString(0),
+                            "Failed trySkipCache on file: {} Error: " + 
wrappedCLibrary.callStrerror(result).getString(0),
                             path);
             }
         }
@@ -243,7 +256,7 @@ public final class CLibrary
 
         try
         {
-            result = fcntl(fd, command, flags);
+            result = wrappedCLibrary.callFcntl(fd, command, flags);
         }
         catch (UnsatisfiedLinkError e)
         {
@@ -266,7 +279,7 @@ public final class CLibrary
 
         try
         {
-            return open(path, O_RDONLY);
+            return wrappedCLibrary.callOpen(path, O_RDONLY);
         }
         catch (UnsatisfiedLinkError e)
         {
@@ -290,7 +303,7 @@ public final class CLibrary
 
         try
         {
-            fsync(fd);
+            wrappedCLibrary.callFsync(fd);
         }
         catch (UnsatisfiedLinkError e)
         {
@@ -301,7 +314,7 @@ public final class CLibrary
             if (!(e instanceof LastErrorException))
                 throw e;
 
-            logger.warn(String.format("fsync(%d) failed, errno (%d) {}", fd, 
errno(e)), e);
+            logger.warn("fsync({}) failed, errorno ({}) {}", fd, errno(e), e);
         }
     }
 
@@ -312,7 +325,7 @@ public final class CLibrary
 
         try
         {
-            close(fd);
+            wrappedCLibrary.callClose(fd);
         }
         catch (UnsatisfiedLinkError e)
         {
@@ -363,4 +376,21 @@ public final class CLibrary
 
         return -1;
     }
+
+    /**
+     * @return the PID of the JVM or -1 if we failed to get the PID
+     */
+    public static long getProcessID()
+    {
+        try
+        {
+            return wrappedCLibrary.callGetpid();
+        }
+        catch (Exception e)
+        {
+            logger.info("Failed to get PID from JNA", e);
+        }
+
+        return -1;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/CLibraryDarwin.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CLibraryDarwin.java 
b/src/java/org/apache/cassandra/utils/CLibraryDarwin.java
new file mode 100644
index 0000000..e0a43ec
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/CLibraryDarwin.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.LastErrorException;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+
+/**
+ * A CLibraryWrapper implementation for Darwin/Mac.
+ * <p>
+ * When JNA is initialized, all methods that have the 'native' keyword
+ * will be attmpted to be linked against. As Java doesn't have the equivalent
+ * of a #ifdef, this means if a native method like posix_fadvise is defined in 
the
+ * class but not available on the target operating system (e.g.
+ * posix_fadvise is not availble on Darwin/Mac) this will cause the entire
+ * initial linking and initialization of JNA to fail. This means other
+ * native calls that are supported on that target operating system will be
+ * unavailable simply because of one native defined method not supported
+ * on the runtime operating system.
+ * @see org.apache.cassandra.utils.CLibraryWrapper
+ * @see CLibrary
+ */
+public class CLibraryDarwin implements CLibraryWrapper
+{
+    private static final Logger logger = 
LoggerFactory.getLogger(CLibraryDarwin.class);
+
+    private static boolean jnaAvailable = true;
+
+    static
+    {
+        try
+        {
+            Native.register("c");
+        }
+        catch (NoClassDefFoundError e)
+        {
+            logger.warn("JNA not found. Native methods will be disabled.");
+            jnaAvailable = false;
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            logger.warn("JNA link failure, one or more native method will be 
unavailable.");
+            logger.error("JNA link failure details: {}", e.getMessage());
+        }
+        catch (NoSuchMethodError e)
+        {
+            logger.warn("Obsolete version of JNA present; unable to register C 
library. Upgrade to JNA 3.2.7 or later");
+            jnaAvailable = false;
+        }
+    }
+
+    private static native int mlockall(int flags) throws LastErrorException;
+    private static native int munlockall() throws LastErrorException;
+    private static native int fcntl(int fd, int command, long flags) throws 
LastErrorException;
+    private static native int open(String path, int flags) throws 
LastErrorException;
+    private static native int fsync(int fd) throws LastErrorException;
+    private static native int close(int fd) throws LastErrorException;
+    private static native Pointer strerror(int errnum) throws 
LastErrorException;
+    private static native long getpid() throws LastErrorException;
+
+    public int callMlockall(int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return mlockall(flags);
+    }
+
+    public int callMunlockall() throws UnsatisfiedLinkError, RuntimeException
+    {
+        return munlockall();
+    }
+
+    public int callFcntl(int fd, int command, long flags) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        return fcntl(fd, command, flags);
+    }
+
+    public int callPosixFadvise(int fd, long offset, int len, int flag) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        // posix_fadvise is not available on Darwin/Mac
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callOpen(String path, int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return open(path, flags);
+    }
+
+    public int callFsync(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        return fsync(fd);
+    }
+
+    public int callClose(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        return close(fd);
+    }
+
+    public Pointer callStrerror(int errnum) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return strerror(errnum);
+    }
+
+    public long callGetpid() throws UnsatisfiedLinkError, RuntimeException
+    {
+        return getpid();
+    }
+
+    public boolean jnaAvailable()
+    {
+        return jnaAvailable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/CLibraryLinux.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CLibraryLinux.java 
b/src/java/org/apache/cassandra/utils/CLibraryLinux.java
new file mode 100644
index 0000000..1822bdf
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/CLibraryLinux.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.LastErrorException;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+
+/**
+ * A CLibraryWrapper implementation for Linux.
+ * <p>
+ * When JNA is initialized, all methods that have the 'native' keyword
+ * will be attmpted to be linked against. As Java doesn't have the equivalent
+ * of a #ifdef, this means if a native method like posix_fadvise is defined in 
the
+ * class but not available on the target operating system (e.g.
+ * posix_fadvise is not availble on Darwin/Mac) this will cause the entire
+ * initial linking and initialization of JNA to fail. This means other
+ * native calls that are supported on that target operating system will be
+ * unavailable simply because of one native defined method not supported
+ * on the runtime operating system.
+ * @see org.apache.cassandra.utils.CLibraryWrapper
+ * @see CLibrary
+ */
+public class CLibraryLinux implements CLibraryWrapper
+{
+    private static boolean jnaAvailable = true;
+
+    private static final Logger logger = 
LoggerFactory.getLogger(CLibraryLinux.class);
+
+    static
+    {
+        try
+        {
+            Native.register("c");
+        }
+        catch (NoClassDefFoundError e)
+        {
+            logger.warn("JNA not found. Native methods will be disabled.");
+            jnaAvailable = false;
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            logger.warn("JNA link failure, one or more native method will be 
unavailable.");
+            logger.error("JNA link failure details: {}", e.getMessage());
+        }
+        catch (NoSuchMethodError e)
+        {
+            logger.warn("Obsolete version of JNA present; unable to register C 
library. Upgrade to JNA 3.2.7 or later");
+            jnaAvailable = false;
+        }
+    }
+
+    private static native int mlockall(int flags) throws LastErrorException;
+    private static native int munlockall() throws LastErrorException;
+    private static native int fcntl(int fd, int command, long flags) throws 
LastErrorException;
+    private static native int posix_fadvise(int fd, long offset, int len, int 
flag) throws LastErrorException;
+    private static native int open(String path, int flags) throws 
LastErrorException;
+    private static native int fsync(int fd) throws LastErrorException;
+    private static native int close(int fd) throws LastErrorException;
+    private static native Pointer strerror(int errnum) throws 
LastErrorException;
+    private static native long getpid() throws LastErrorException;
+
+    public int callMlockall(int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return mlockall(flags);
+    }
+
+    public int callMunlockall() throws UnsatisfiedLinkError, RuntimeException
+    {
+        return munlockall();
+    }
+
+    public int callFcntl(int fd, int command, long flags) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        return fcntl(fd, command, flags);
+    }
+
+    public int callPosixFadvise(int fd, long offset, int len, int flag) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        return posix_fadvise(fd, offset, len, flag);
+    }
+
+    public int callOpen(String path, int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return open(path, flags);
+    }
+
+    public int callFsync(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        return fsync(fd);
+    }
+
+    public int callClose(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        return close(fd);
+    }
+
+    public Pointer callStrerror(int errnum) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        return strerror(errnum);
+    }
+
+    public long callGetpid() throws UnsatisfiedLinkError, RuntimeException
+    {
+        return getpid();
+    }
+
+    public boolean jnaAvailable()
+    {
+        return jnaAvailable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/CLibraryWindows.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CLibraryWindows.java 
b/src/java/org/apache/cassandra/utils/CLibraryWindows.java
new file mode 100644
index 0000000..c8b5bbb
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/CLibraryWindows.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.Pointer;
+
+/**
+ * A CLibraryWrapper implementation for Windows.
+ * <p>
+ * As libc isn't available on Windows these implementations
+ * will obviously be a no-op, however when possible implementations
+ * are used that are Windows friendly that will return the same
+ * return value.
+ * @see org.apache.cassandra.utils.CLibraryWrapper
+ * @see CLibrary
+ */
+public class CLibraryWindows implements CLibraryWrapper
+{
+    private static final Logger logger = 
LoggerFactory.getLogger(CLibraryWindows.class);
+
+    public int callMlockall(int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callMunlockall() throws UnsatisfiedLinkError, RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callFcntl(int fd, int command, long flags) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callPosixFadvise(int fd, long offset, int len, int flag) throws 
UnsatisfiedLinkError, RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callOpen(String path, int flags) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callFsync(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public int callClose(int fd) throws UnsatisfiedLinkError, RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    public Pointer callStrerror(int errnum) throws UnsatisfiedLinkError, 
RuntimeException
+    {
+        throw new UnsatisfiedLinkError();
+    }
+
+    /**
+     * @return the PID of the JVM running
+     * @throws UnsatisfiedLinkError if we fail to link against Sigar
+     * @throws RuntimeException if another unexpected error is thrown by Sigar
+     */
+    public long callGetpid() throws UnsatisfiedLinkError, RuntimeException
+    {
+        try
+        {
+            return SigarLibrary.instance.getPid();
+        }
+        catch (Exception e)
+        {
+            logger.error("Failed to initialize or use Sigar Library", e);
+        }
+
+        return -1;
+    }
+
+    public boolean jnaAvailable()
+    {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/CLibraryWrapper.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CLibraryWrapper.java 
b/src/java/org/apache/cassandra/utils/CLibraryWrapper.java
new file mode 100644
index 0000000..b97fa64
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/CLibraryWrapper.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.utils;
+
+import com.sun.jna.Pointer;
+
+/**
+ * An interface to implement for using OS specific native methods.
+ * @see CLibrary
+ */
+interface CLibraryWrapper
+{
+    boolean jnaAvailable();
+
+    int callMlockall(int flags) throws UnsatisfiedLinkError, RuntimeException;
+    int callMunlockall() throws UnsatisfiedLinkError, RuntimeException;
+    int callFcntl(int fd, int command, long flags) throws 
UnsatisfiedLinkError, RuntimeException;
+    int callPosixFadvise(int fd, long offset, int len, int flag) throws 
UnsatisfiedLinkError, RuntimeException;
+    int callOpen(String path, int flags) throws UnsatisfiedLinkError, 
RuntimeException;
+    int callFsync(int fd) throws UnsatisfiedLinkError, RuntimeException;
+    int callClose(int fd) throws UnsatisfiedLinkError, RuntimeException;
+    Pointer callStrerror(int errnum) throws UnsatisfiedLinkError, 
RuntimeException;
+    long callGetpid() throws UnsatisfiedLinkError, RuntimeException;
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/HeapUtils.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/HeapUtils.java 
b/src/java/org/apache/cassandra/utils/HeapUtils.java
index bfc8a0b..34b1b58 100644
--- a/src/java/org/apache/cassandra/utils/HeapUtils.java
+++ b/src/java/org/apache/cassandra/utils/HeapUtils.java
@@ -168,11 +168,9 @@ public final class HeapUtils
      */
     private static Long getProcessId()
     {
-        // Once Java 9 is ready the process API should provide a better way to 
get the process ID.
-        long pid = SigarLibrary.instance.getPid();
-
+        long pid = CLibrary.getProcessID();
         if (pid >= 0)
-            return Long.valueOf(pid);
+            return pid;
 
         return getProcessIdFromJvmName();
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/src/java/org/apache/cassandra/utils/UUIDGen.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/UUIDGen.java 
b/src/java/org/apache/cassandra/utils/UUIDGen.java
index 3efcb5e..66649c2 100644
--- a/src/java/org/apache/cassandra/utils/UUIDGen.java
+++ b/src/java/org/apache/cassandra/utils/UUIDGen.java
@@ -360,7 +360,7 @@ public class UUIDGen
                 messageDigest.update(addr.getAddress());
 
             // Identify the process on the load: we use both the PID and class 
loader hash.
-            long pid = SigarLibrary.instance.getPid();
+            long pid = CLibrary.getProcessID();
             if (pid < 0)
                 pid = new Random(System.currentTimeMillis()).nextLong();
             FBUtilities.updateWithLong(messageDigest, pid);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e3968cfd/test/unit/org/apache/cassandra/utils/CLibraryTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/CLibraryTest.java 
b/test/unit/org/apache/cassandra/utils/CLibraryTest.java
index 7516392..d07b1ff 100644
--- a/test/unit/org/apache/cassandra/utils/CLibraryTest.java
+++ b/test/unit/org/apache/cassandra/utils/CLibraryTest.java
@@ -20,6 +20,7 @@ package org.apache.cassandra.utils;
 
 import java.io.File;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 import org.apache.cassandra.io.util.FileUtils;
@@ -33,4 +34,11 @@ public class CLibraryTest
 
         CLibrary.trySkipCache(file.getPath(), 0, 0);
     }
+
+    @Test
+    public void getPid()
+    {
+        long pid = CLibrary.getProcessID();
+        Assert.assertTrue(pid > 0);
+    }
 }

Reply via email to