diff --git a/loader/icd.c b/loader/icd.c index ea4c3f5d..48579b39 100644 --- a/loader/icd.c +++ b/loader/icd.c @@ -79,6 +79,17 @@ void khrIcdVendorAdd(const char *libraryName) goto Done; } + // get the library's file name + const char *libName = libraryName; + const char *c; + for (c = libraryName; *c; ++c) + { + if (*c == DIRECTORY_SYMBOL) + { + libName = c + 1; + } + } + // ensure that we haven't already loaded this vendor for (vendorIterator = khrIcdVendors; vendorIterator; vendorIterator = vendorIterator->next) { @@ -87,6 +98,11 @@ void khrIcdVendorAdd(const char *libraryName) KHR_ICD_TRACE("already loaded vendor %s, nothing to do here\n", libraryName); goto Done; } + if (!strcmp(vendorIterator->libName, libName)) + { + KHR_ICD_TRACE("already loaded library %s, nothing to do here\n", libName); + goto Done; + } } // get the library's clGetExtensionFunctionAddress pointer @@ -184,6 +200,8 @@ void khrIcdVendorAdd(const char *libraryName) KHR_ICD_TRACE("failed get platform handle to library\n"); continue; } + vendor->libName = (char *)malloc(strlen(libName) + 1); + strcpy(vendor->libName, libName); vendor->clGetExtensionFunctionAddress = p_clGetExtensionFunctionAddress; vendor->platform = platforms[i]; vendor->suffix = suffix; @@ -417,3 +435,15 @@ void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, } } +void khrIcdFreeLibName() +{ + KHRicdVendor *vendorIterator; + for (vendorIterator = khrIcdVendors; vendorIterator; vendorIterator = vendorIterator->next) + { + if (vendorIterator->libName != NULL) + { + free(vendorIterator->libName); + vendorIterator->libName = NULL; + } + } +} \ No newline at end of file diff --git a/loader/icd.h b/loader/icd.h index 13b64fd6..8890e41d 100644 --- a/loader/icd.h +++ b/loader/icd.h @@ -69,6 +69,9 @@ struct KHRicdVendorRec // the loaded library object (true type varies on Linux versus Windows) void *library; + // the file name of the library + char *libName; + // the extension suffix for this platform char *suffix; @@ -160,6 +163,9 @@ void khrIcdContextPropertiesGetPlatform( const cl_context_properties *properties, cl_platform_id *outPlatform); +// free libName in KHRicdVendorRec struct +void khrIcdFreeLibName(); + // internal tracing macros #define KHR_ICD_TRACE(...) \ do \ diff --git a/loader/linux/icd_linux.c b/loader/linux/icd_linux.c index e404b6f9..95573631 100644 --- a/loader/linux/icd_linux.c +++ b/loader/linux/icd_linux.c @@ -145,6 +145,8 @@ void khrIcdOsVendorsEnumerate(void) closedir(dir); } + khrIcdFreeLibName(); + if (NULL != envPath) { khrIcd_free_getenv(envPath); diff --git a/loader/windows/icd_windows.c b/loader/windows/icd_windows.c index f26cfe51..8efb998b 100644 --- a/loader/windows/icd_windows.c +++ b/loader/windows/icd_windows.c @@ -247,6 +247,9 @@ BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVO { KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName); } + + khrIcdFreeLibName(); + #if defined(CL_ENABLE_LAYERS) khrIcdLayersEnumerateEnv(); #endif // defined(CL_ENABLE_LAYERS)