Set parent namespace for linker-namespaces
This change allows applications to share RTLD_GLOBAL native libraries between namespaces associated with different classloaders. The rule is - if a library is GLOBAL within namespace associated with parent classloader, it is shared with namespace associated with this classloader Note that the sharing happens on create_namespace event, which is tied to createClassloader in case of application classloaders created by the framework, for custom application classloaders it is tied to first loadLibrary() event. Bug: http://b/28560538 Bug: https://code.google.com/p/android/issues/detail?id=208458 Change-Id: I7ee701166f8ec5eff033b7acc0f80c7aa4ec5bda
This commit is contained in:
parent
a214a769f9
commit
24db75c1ce
|
@ -83,7 +83,8 @@ extern struct android_namespace_t* android_create_namespace(const char* name,
|
|||
const char* ld_library_path,
|
||||
const char* default_library_path,
|
||||
uint64_t type,
|
||||
const char* permitted_when_isolated_path);
|
||||
const char* permitted_when_isolated_path,
|
||||
android_namespace_t* parent);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -95,11 +95,14 @@ class LibraryNamespaces {
|
|||
namespace_type |= ANDROID_NAMESPACE_TYPE_SHARED;
|
||||
}
|
||||
|
||||
android_namespace_t* parent_ns = FindParentNamespaceByClassLoader(env, class_loader);
|
||||
|
||||
ns = android_create_namespace("classloader-namespace",
|
||||
nullptr,
|
||||
library_path.c_str(),
|
||||
namespace_type,
|
||||
permitted_path.c_str());
|
||||
permitted_path.c_str(),
|
||||
parent_ns);
|
||||
|
||||
if (ns != nullptr) {
|
||||
namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
|
||||
|
@ -200,6 +203,29 @@ class LibraryNamespaces {
|
|||
return initialized_;
|
||||
}
|
||||
|
||||
jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) {
|
||||
jclass class_loader_class = env->FindClass("java/lang/ClassLoader");
|
||||
jmethodID get_parent = env->GetMethodID(class_loader_class,
|
||||
"getParent",
|
||||
"()Ljava/lang/ClassLoader;");
|
||||
|
||||
return env->CallObjectMethod(class_loader, get_parent);
|
||||
}
|
||||
|
||||
android_namespace_t* FindParentNamespaceByClassLoader(JNIEnv* env, jobject class_loader) {
|
||||
jobject parent_class_loader = GetParentClassLoader(env, class_loader);
|
||||
|
||||
while (parent_class_loader != nullptr) {
|
||||
android_namespace_t* ns = FindNamespaceByClassLoader(env, parent_class_loader);
|
||||
if (ns != nullptr) {
|
||||
return ns;
|
||||
}
|
||||
|
||||
parent_class_loader = GetParentClassLoader(env, parent_class_loader);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool initialized_;
|
||||
std::vector<std::pair<jweak, android_namespace_t*>> namespaces_;
|
||||
std::string public_libraries_;
|
||||
|
|
Loading…
Reference in New Issue