package one.nio.os;
import one.nio.mgt.Management;
import one.nio.util.ByteArrayBuilder;
import one.nio.util.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.CRC32;
public final class NativeLibrary implements NativeLibraryMXBean {
private static final Log log = LogFactory.getLog(NativeLibrary.class);
public static final boolean IS_SUPPORTED = isSupportedOs() && loadNativeLibrary();
private static boolean isSupportedOs() {
return System.getProperty("os.name").toLowerCase().contains("linux") &&
System.getProperty("os.arch").contains("64");
}
private static boolean loadNativeLibrary() {
try {
InputStream in = NativeLibrary.class.getResourceAsStream("/libonenio.so");
if (in == null) {
log.error("Cannot find native IO library");
return false;
}
ByteArrayBuilder libData = readStream(in);
in.close();
String tmpDir = System.getProperty("java.io.tmpdir", "/tmp");
File dll = new File(tmpDir, "libonenio." + crc32(libData) + ".so");
if (!dll.exists()) {
OutputStream out = new FileOutputStream(dll);
out.write(libData.buffer(), 0, libData.length());
out.close();
}
String libraryPath = dll.getAbsolutePath();
System.load(libraryPath);
Management.registerMXBean(new NativeLibrary(libraryPath), "one.nio.os:type=NativeLibrary");
return true;
} catch (Throwable e) {
log.error("Cannot load native IO library", e);
return false;
}
}
private static ByteArrayBuilder readStream(InputStream in) throws IOException {
byte[] buffer = new byte[64000];
ByteArrayBuilder builder = new ByteArrayBuilder(buffer.length);
for (int bytes; (bytes = in.read(buffer)) > 0; ) {
builder.append(buffer, 0, bytes);
}
return builder;
}
private static String crc32(ByteArrayBuilder builder) {
CRC32 crc32 = new CRC32();
crc32.update(builder.buffer(), 0, builder.length());
return Hex.toHex((int) crc32.getValue());
}
// MXBean interface
private final String libraryPath;
private NativeLibrary(String libraryPath) {
this.libraryPath = libraryPath;
}
@Override
public String getLibraryPath() {
return libraryPath;
}
@Override
public int mlockall(int flags) {
return Mem.mlockall(flags);
}
@Override
public int munlockall() {
return Mem.munlockall();
}
@Override
public int sched_setaffinity(int pid, long mask) {
return Proc.sched_setaffinity(pid, mask);
}
@Override
public long sched_getaffinity(int pid) {
return Proc.sched_getaffinity(pid);
}
}