I dynamically load the library with dlopen and then close its dlclose . I expected all library resources to be freed after dlclose completes, but after calling dlclose , open file descriptors from the library still remain. I am wondering how to make sure that the library is unloaded in the middle of the program so that it cleans up all its resources.
My code is below:
#include <CL/cl.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <dlfcn.h> #include <string.h> #include <dirent.h> #include <fcntl.h> #include <unistd.h> #define MAX_PATH_LENGTH 80 int deviceQ() { cl_int ret; void * libHandle = dlopen("/usr/lib64/libOpenCL.so", RTLD_LAZY); cl_int (* clGetPlatformIDs)(cl_uint, cl_platform_id*, cl_uint*) = dlsym( libHandle, "clGetPlatformIDs" ); cl_int (* clGetDeviceIDs)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*) = dlsym(libHandle, "clGetDeviceIDs"); /********************** PREAMBLE **************************************/ cl_device_id device_id = NULL; cl_platform_id platform_id = NULL; cl_uint ret_num_devices; cl_uint ret_num_platforms; ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms); if (ret != CL_SUCCESS) { perror("Failed to get platform IDs"); } else if (ret_num_platforms != 1) { fprintf(stderr, "Number of platforms returned is %d\n", ret_num_platforms); exit(1); } printf("Read platform IDs\n"); ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &ret_num_devices); if (ret != CL_SUCCESS) { perror("Failed to get device IDs"); } else if (ret_num_devices != 1) { fprintf(stderr, "Number of returned devices is %d\n", ret_num_devices); exit(1); } printf("Read device IDs\n"); /********************** PREAMBLE **************************************/ /***************** RELEASE AND FREE ****************************/ dlclose(libHandle); /***************** RELEASE AND FREE ****************************/ return 0; } size_t closeFileDescriptors(void ** arr) { // step 1 - get PID pid_t pid = getpid(); //printf("PID is %d\n", pid); char path[MAX_PATH_LENGTH]; memset(path, '\0', MAX_PATH_LENGTH); sprintf(path, "/proc/%d/fd", pid); int fd; DIR * d = opendir(path); struct dirent *dir; struct stat s; char dirPath[MAX_PATH_LENGTH]; char realPath[MAX_PATH_LENGTH]; size_t index = 0; if (d) { while ((dir = readdir(d)) != NULL) { if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) { fd = atoi(dir->d_name); if (fstat(fd, &s) != 0) { perror("fstat failed"); } memset(dirPath, '\0', MAX_PATH_LENGTH); strcpy(dirPath, path); strcat(dirPath, "/"); strcat(dirPath, dir->d_name); #ifdef S_IFLNK if (s.st_mode & S_IFLNK) { #else if (S_ISLNK(s.st_mode)) { #endif memset(realPath, '\0', MAX_PATH_LENGTH); #ifdef readlink readlink(dirPath, realPath, MAX_PATH_LENGTH); printf("%s -> %s\n", dirPath, realPath); #else printf("[readlink not defined] %s\n", dirPath); #endif } else { printf("Not link: %s (proceeding anyway)\n", dirPath); //printf("Not link: %s (ignoring)\n", dirPath); //continue; } if (fd > 2) { //int fdFlags = fcntl(fd, F_GETFD); int fdFlags = fcntl(fd, F_GETFL); if (fdFlags == -1) { perror("fcntl failed"); } //off_t offset = lseek(fd, 0, SEEK_CUR); off_t offset = 0; if (offset == -1) { perror("lseek failed"); } if (arr != NULL) { /* arr[index] = (fileData *) malloc(sizeof (fileData)); arr[index]->flags = fdFlags; arr[index]->offset = offset; arr[index]->fd = fd; strcpy(arr[index]->fdPath, realPath);*/ } index++; // ignore stdin, stdout, stderr printf("Closing FD %d (flags %d, offset %zd)\n", fd, fdFlags, offset); close(fd); } } } closedir(d); } else { fprintf(stderr, "Could not open directory %s\n", path); } return index; } int main () { deviceQ(); printf("=> Closing open file descriptors\n"); closeFileDescriptors (NULL); deviceQ(); return 0; }