@@ -906,10 +906,11 @@ struct TableLocker {
906906 ~TableLocker () { pthread_mutex_unlock (&g_handletable_mutex); }
907907};
908908struct handletableentry {
909- void * handle;
910- ino64_t inode;
911- dev64_t devid;
912- uint refcount;
909+ void * handle;
910+ ino64_t inode;
911+ dev64_t devid;
912+ char * member;
913+ uint refcount;
913914};
914915constexpr unsigned init_num_handles = 128 ;
915916static unsigned max_handletable = 0 ;
@@ -1049,14 +1050,25 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
10491050 return nullptr ;
10501051 }
10511052 else {
1053+ // extract member string if exist duplicate it and store pointer of it
1054+ // if member does not exist store nullptr
1055+ char * member = nullptr ;
1056+ const char * substr;
1057+ if (filename[strlen (filename) - 1 ] == ' )' && (substr = strrchr (filename, ' (' ))) {
1058+ member = os::strdup (substr);
1059+ }
1060+
10521061 unsigned i = 0 ;
10531062 TableLocker lock;
10541063 // check if library belonging to filename is already loaded.
10551064 // If yes use stored handle from previous ::dlopen() and increase refcount
10561065 for (i = 0 ; i < g_handletable_used; i++) {
10571066 if ((p_handletable + i)->handle &&
10581067 (p_handletable + i)->inode == libstat.st_ino &&
1059- (p_handletable + i)->devid == libstat.st_dev ) {
1068+ (p_handletable + i)->devid == libstat.st_dev &&
1069+ (((p_handletable + i)->member == nullptr && member == nullptr ) ||
1070+ ((p_handletable + i)->member != nullptr && member != nullptr &&
1071+ strcmp ((p_handletable + i)->member , member) == 0 ))) {
10601072 (p_handletable + i)->refcount ++;
10611073 result = (p_handletable + i)->handle ;
10621074 break ;
@@ -1084,6 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
10841096 (p_handletable + i)->handle = result;
10851097 (p_handletable + i)->inode = libstat.st_ino ;
10861098 (p_handletable + i)->devid = libstat.st_dev ;
1099+ (p_handletable + i)->member = member;
10871100 (p_handletable + i)->refcount = 1 ;
10881101 }
10891102 else {
@@ -1131,7 +1144,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
11311144 // while in the second case we simply have to nag.
11321145 res = (0 == ::dlclose (libhandle));
11331146 if (!res) {
1134- // error analysis when dlopen fails
1147+ // error analysis when dlclose fails
11351148 const char * error_report = ::dlerror ();
11361149 if (error_report == nullptr ) {
11371150 error_report = " dlerror returned no error description" ;
@@ -1145,7 +1158,11 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
11451158 if (i < g_handletable_used) {
11461159 if (res) {
11471160 // First case: libhandle was found (with refcount == 0) and ::dlclose successful,
1148- // so delete entry from array
1161+ // so delete entry from array (do not forget to free member-string space if member exists)
1162+ if ((p_handletable + i)->member ) {
1163+ os::free ((p_handletable + i)->member );
1164+ (p_handletable + i)->member = nullptr ;
1165+ }
11491166 g_handletable_used--;
11501167 // If the entry was the last one of the array, the previous g_handletable_used--
11511168 // is sufficient to remove the entry from the array, otherwise we move the last
0 commit comments