java/com/jetbrains/cef/SharedMemory.java (146 lines of code) (raw):

package com.jetbrains.cef; import com.jetbrains.cef.remote.NativeServerManager; import org.cef.OS; import org.cef.SystemBootstrap; import org.cef.misc.CefLog; import org.cef.misc.Utils; import java.io.File; import java.nio.ByteBuffer; public class SharedMemory { private static final String ALT_MEM_HELPER_PATH; private static volatile boolean isLoaded = false; public final String mname; public final long boostHandle; public long lasUsedMs = 0; final private long mySegment; final private long myPtr; final private long myMutex; static { final String altMemHelperPath = Utils.getString("ALT_MEM_HELPER_PATH"); if (altMemHelperPath != null && !altMemHelperPath.trim().isEmpty()) ALT_MEM_HELPER_PATH = altMemHelperPath.trim(); else if (NativeServerManager.ALT_CEF_SERVER_PATH != null && !NativeServerManager.ALT_CEF_SERVER_PATH.trim().isEmpty()) { File libDir = new File(NativeServerManager.ALT_CEF_SERVER_PATH).getParentFile(); String libName; if (OS.isWindows()) libName = "shared_mem_helper.dll"; else if (OS.isLinux()) libName = "libshared_mem_helper.so"; else { // libshared_mem_helper.dylib is usually place near cef_server.app but ALT_CEF_SERVER_PATH is like cef_server.app/Contents/MacOS/cef_server libDir = libDir.getParentFile().getParentFile().getParentFile(); libName = "libshared_mem_helper.dylib"; } ALT_MEM_HELPER_PATH = new File(libDir, libName).getAbsolutePath(); } else ALT_MEM_HELPER_PATH = null; loadDynamicLib(); } public static boolean isIsLoaded() { return isLoaded; } public static void loadDynamicLib() { if (isLoaded) return; try { if (ALT_MEM_HELPER_PATH == null || ALT_MEM_HELPER_PATH.isEmpty()) { CefLog.Debug("Load shared_mem_helper library from jbr bundle."); SystemBootstrap.loadLibrary("shared_mem_helper"); } else { CefLog.Debug("Load shared_mem_helper library from alt path %s", ALT_MEM_HELPER_PATH); System.load(ALT_MEM_HELPER_PATH.trim()); } isLoaded = true; } catch (UnsatisfiedLinkError e) { CefLog.Error("Can't load shared_mem_helper, exception: %s", e.getMessage()); } } public static void loadDynamicLib(String path) { if (isLoaded) return; try { CefLog.Debug("Load shared_mem_helper library from file %s", path); System.load(path.trim()); isLoaded = true; } catch (UnsatisfiedLinkError e) { CefLog.Error("Can't load shared_mem_helper, exception: %s", e.getMessage()); } } public SharedMemory(String sharedMemName, long boostHandle) { mname = sharedMemName; this.boostHandle = boostHandle; this.mySegment = openSharedSegment(sharedMemName); this.myPtr = getPointer(mySegment, boostHandle); myMutex = openSharedMutex(sharedMemName); } public void lock() { lockSharedMutex(myMutex); } public void unlock() { unlockSharedMutex(myMutex); } public long getPtr() { return myPtr; } @Override protected void finalize() throws Throwable { try { closeSharedSegment(mySegment); closeSharedMutex(myMutex); } finally { super.finalize(); } } public ByteBuffer wrap(int size) { return wrapNativeMem(myPtr, size); } public int readInt() { return readInt(myPtr, 0); } public int readInt(int offset) { return readInt(myPtr, offset); } public int readByte(int offset) { return readByte(myPtr, offset); } // Helper method (for creating BufferedImage from native raster) private static native ByteBuffer wrapNativeMem(long pdata, int length); private static native int readInt(long pdata, int offset); private static native int readByte(long pdata, int offset); public static class WithRaster extends SharedMemory { private int myWidth; private int myHeight; private int myDirtyRectsCount; public WithRaster(String sharedMemName, long boostHandle) { super(sharedMemName, boostHandle); } public ByteBuffer wrapRaster() { return wrapNativeMem(getPtr(), myWidth * myHeight * 4); } public ByteBuffer wrapRects() { return wrapNativeMem(getPtr() + getRectsOffset(), myDirtyRectsCount * 4 * 4); } public int getRectsOffset() { return myWidth * myHeight * 4; } public int getWidth() { return myWidth; } public void setWidth(int width) { this.myWidth = width; } public int getHeight() { return myHeight; } public void setHeight(int height) { this.myHeight = height; } public int getDirtyRectsCount() { return myDirtyRectsCount; } public void setDirtyRectsCount(int dirtyRectsCount) { this.myDirtyRectsCount = dirtyRectsCount; } } // // Private native API // private static native long openSharedSegment(String sid); private static native long getPointer(long segment, long handle); private static native void closeSharedSegment(long segment); private static native long openSharedMutex(String uid); private static native void lockSharedMutex(long mutex); private static native void unlockSharedMutex(long mutex); private static native void closeSharedMutex(long mutex); }