Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions src/hotspot/os/aix/porting_aix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,10 +906,11 @@ struct TableLocker {
~TableLocker() { pthread_mutex_unlock(&g_handletable_mutex); }
};
struct handletableentry{
void* handle;
ino64_t inode;
dev64_t devid;
uint refcount;
void* handle;
ino64_t inode;
dev64_t devid;
char* member;
uint refcount;
};
constexpr unsigned init_num_handles = 128;
static unsigned max_handletable = 0;
Expand Down Expand Up @@ -1049,14 +1050,25 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
return nullptr;
}
else {
// extract member string if exist duplicate it and store pointer of it
// if member does not exist store nullptr
char* member = nullptr;
const char* substr;
if (filename[strlen(filename) - 1] == ')' && (substr = strrchr(filename, '('))) {
member = os::strdup(substr);
}

unsigned i = 0;
TableLocker lock;
// check if library belonging to filename is already loaded.
// If yes use stored handle from previous ::dlopen() and increase refcount
for (i = 0; i < g_handletable_used; i++) {
if ((p_handletable + i)->handle &&
(p_handletable + i)->inode == libstat.st_ino &&
(p_handletable + i)->devid == libstat.st_dev) {
(p_handletable + i)->devid == libstat.st_dev &&
(((p_handletable + i)->member == nullptr && member == nullptr) ||
((p_handletable + i)->member != nullptr && member != nullptr &&
strcmp((p_handletable + i)->member, member) == 0))) {
(p_handletable + i)->refcount++;
result = (p_handletable + i)->handle;
break;
Expand Down Expand Up @@ -1084,6 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
(p_handletable + i)->handle = result;
(p_handletable + i)->inode = libstat.st_ino;
(p_handletable + i)->devid = libstat.st_dev;
(p_handletable + i)->member = member;
(p_handletable + i)->refcount = 1;
}
else {
Expand Down Expand Up @@ -1131,7 +1144,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
// while in the second case we simply have to nag.
res = (0 == ::dlclose(libhandle));
if (!res) {
// error analysis when dlopen fails
// error analysis when dlclose fails
const char* error_report = ::dlerror();
if (error_report == nullptr) {
error_report = "dlerror returned no error description";
Expand All @@ -1145,7 +1158,11 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
if (i < g_handletable_used) {
if (res) {
// First case: libhandle was found (with refcount == 0) and ::dlclose successful,
// so delete entry from array
// so delete entry from array (do not forget to free member-string space if member exists)
if ((p_handletable + i)->member) {
os::free((p_handletable + i)->member);
(p_handletable + i)->member = nullptr;
}
g_handletable_used--;
// If the entry was the last one of the array, the previous g_handletable_used--
// is sufficient to remove the entry from the array, otherwise we move the last
Expand Down