Skip to content
Snippets Groups Projects
Commit 8c0eea0c authored by Mick Jordan's avatar Mick Jordan
Browse files

replace Semaphore with synchronized; add embedded DLLInfo to list

parent 3b10e54c
Branches
No related tags found
No related merge requests found
......@@ -127,7 +127,7 @@ public class DLL {
private boolean forceSymbols;
private DotSymbol[][] nativeSymbols = new DotSymbol[NativeSymbolType.values().length][];
DLLInfo(String name, String path, boolean dynamicLookup, Object handle) {
private DLLInfo(String name, String path, boolean dynamicLookup, Object handle) {
this.id = ID.getAndIncrement();
this.name = name;
this.path = path;
......@@ -135,6 +135,12 @@ public class DLL {
this.handle = handle;
}
private static synchronized DLLInfo create(String name, String path, boolean dynamicLookup, Object handle) {
DLLInfo result = new DLLInfo(name, path, dynamicLookup, handle);
list.add(result);
return result;
}
public void setNativeSymbols(int nstOrd, DotSymbol[] symbols) {
nativeSymbols[nstOrd] = symbols;
}
......@@ -270,8 +276,6 @@ public class DLL {
}
}
private static final Semaphore listCritical = new Semaphore(1, false);
/*
* There is no sense in throwing an RError if we fail to load/init a (default) package during
* initial context initialization, as it is essentially fatal for any of the standard packages
......@@ -281,43 +285,33 @@ public class DLL {
*/
@TruffleBoundary
public static DLLInfo load(String path, boolean local, boolean now) throws DLLException {
public static synchronized DLLInfo load(String path, boolean local, boolean now) throws DLLException {
String absPath = Utils.tildeExpand(path);
try {
listCritical.acquire();
for (DLLInfo dllInfo : list) {
if (dllInfo.path.equals(absPath)) {
// already loaded
return dllInfo;
}
}
File file = new File(absPath);
Object handle = RFFIFactory.getRFFI().getBaseRFFI().dlopen(absPath, local, now);
if (handle == null) {
String dlError = RFFIFactory.getRFFI().getBaseRFFI().dlerror();
if (RContext.isInitialContextInitialized()) {
throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, dlError);
} else {
throw Utils.rSuicide("error loading default package: " + path + "\n" + dlError);
}
for (DLLInfo dllInfo : list) {
if (dllInfo.path.equals(absPath)) {
// already loaded
return dllInfo;
}
String name = file.getName();
int dx = name.lastIndexOf('.');
if (dx > 0) {
name = name.substring(0, dx);
}
File file = new File(absPath);
Object handle = RFFIFactory.getRFFI().getBaseRFFI().dlopen(absPath, local, now);
if (handle == null) {
String dlError = RFFIFactory.getRFFI().getBaseRFFI().dlerror();
if (RContext.isInitialContextInitialized()) {
throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, dlError);
} else {
throw Utils.rSuicide("error loading default package: " + path + "\n" + dlError);
}
DLLInfo result = new DLLInfo(name, absPath, true, handle);
list.add(result);
return result;
} catch (InterruptedException ex) {
throw RInternalError.shouldNotReachHere();
} finally {
listCritical.release();
}
String name = file.getName();
int dx = name.lastIndexOf('.');
if (dx > 0) {
name = name.substring(0, dx);
}
return DLLInfo.create(name, absPath, true, handle);
}
private static final String R_INIT_PREFIX = "R_init_";
private static final Semaphore initCritical = new Semaphore(1, false);
@TruffleBoundary
public static DLLInfo loadPackageDLL(String path, boolean local, boolean now) throws DLLException {
......@@ -326,8 +320,7 @@ public class DLL {
String pkgInit = R_INIT_PREFIX + dllInfo.name;
long initFunc = RFFIFactory.getRFFI().getBaseRFFI().dlsym(dllInfo.handle, pkgInit);
if (initFunc != 0) {
try {
initCritical.acquire();
synchronized (DLL.class) {
try {
RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(initFunc, pkgInit, new Object[]{dllInfo});
} catch (ReturnException ex) {
......@@ -341,33 +334,22 @@ public class DLL {
throw Utils.rSuicide(RError.Message.DLL_RINIT_ERROR.message + " on default package: " + path);
}
}
} catch (InterruptedException ex) {
throw RInternalError.shouldNotReachHere();
} finally {
initCritical.release();
}
}
return dllInfo;
}
@TruffleBoundary
public static void unload(String path) throws DLLException {
public static synchronized void unload(String path) throws DLLException {
String absPath = Utils.tildeExpand(path);
try {
listCritical.acquire();
for (DLLInfo info : list) {
if (info.path.equals(absPath)) {
int rc = RFFIFactory.getRFFI().getBaseRFFI().dlclose(info.handle);
if (rc != 0) {
throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, "");
}
return;
for (DLLInfo info : list) {
if (info.path.equals(absPath)) {
int rc = RFFIFactory.getRFFI().getBaseRFFI().dlclose(info.handle);
if (rc != 0) {
throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, "");
}
return;
}
} catch (InterruptedException ex) {
throw RInternalError.shouldNotReachHere();
} finally {
listCritical.release();
}
throw new DLLException(RError.Message.DLL_NOT_LOADED, path);
}
......@@ -455,49 +437,35 @@ public class DLL {
* {@code null})
*/
@TruffleBoundary
public static long findSymbol(String name, String libName, RegisteredNativeSymbol rns) {
public static synchronized long findSymbol(String name, String libName, RegisteredNativeSymbol rns) {
boolean all = libName == null || libName.length() == 0;
try {
listCritical.acquire();
for (DLLInfo dllInfo : list) {
if (dllInfo.forceSymbols) {
continue;
}
if (all || dllInfo.name.equals(libName)) {
long func = dlsym(dllInfo, name, rns);
if (func != SYMBOL_NOT_FOUND) {
if (rns != null) {
rns.dllInfo = dllInfo;
}
return func;
for (DLLInfo dllInfo : list) {
if (dllInfo.forceSymbols) {
continue;
}
if (all || dllInfo.name.equals(libName)) {
long func = dlsym(dllInfo, name, rns);
if (func != SYMBOL_NOT_FOUND) {
if (rns != null) {
rns.dllInfo = dllInfo;
}
}
if (!all && dllInfo.name.equals(libName)) {
return SYMBOL_NOT_FOUND;
return func;
}
}
return SYMBOL_NOT_FOUND;
} catch (InterruptedException ex) {
throw RInternalError.shouldNotReachHere();
} finally {
listCritical.release();
if (!all && dllInfo.name.equals(libName)) {
return SYMBOL_NOT_FOUND;
}
}
return SYMBOL_NOT_FOUND;
}
public static DLLInfo findLibrary(String name) {
try {
listCritical.acquire();
for (DLLInfo dllInfo : list) {
if (dllInfo.name.equals(name)) {
return dllInfo;
}
public static synchronized DLLInfo findLibrary(String name) {
for (DLLInfo dllInfo : list) {
if (dllInfo.name.equals(name)) {
return dllInfo;
}
return null;
} catch (InterruptedException ex) {
throw RInternalError.shouldNotReachHere();
} finally {
listCritical.release();
}
return null;
}
@TruffleBoundary
......@@ -533,7 +501,7 @@ public class DLL {
public static DLLInfo getEmbeddingDLLInfo() {
DLLInfo result = findLibrary(EMBEDDING);
if (result == null) {
result = new DLLInfo(EMBEDDING, EMBEDDING, false, null);
result = DLLInfo.create(EMBEDDING, EMBEDDING, false, null);
}
return result;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment