| 57 | } |
| 58 | |
| 59 | cache_t *create_cache_internal(const char *const cache_alg_name, |
| 60 | common_cache_params_t cc_params, |
| 61 | void *cache_specific_params) { |
| 62 | cache_t *(*cache_init)(common_cache_params_t, void *) = NULL; |
| 63 | char *err = NULL; |
| 64 | |
| 65 | char cache_init_func_name[256]; |
| 66 | void *handle = dlopen(NULL, RTLD_GLOBAL); |
| 67 | /* should not check err here, otherwise ubuntu will report err even though |
| 68 | * everything is OK */ |
| 69 | |
| 70 | sprintf(cache_init_func_name, "%s_init", cache_alg_name); |
| 71 | |
| 72 | // ISO C compliant way to convert void* to function pointer |
| 73 | union { |
| 74 | void *obj_ptr; |
| 75 | cache_t *(*func_ptr)(common_cache_params_t, void *); |
| 76 | } dlsym_ptr; |
| 77 | |
| 78 | dlsym_ptr.obj_ptr = dlsym(handle, cache_init_func_name); |
| 79 | cache_init = dlsym_ptr.func_ptr; |
| 80 | |
| 81 | err = dlerror(); |
| 82 | |
| 83 | if (cache_init == NULL) { |
| 84 | WARN("cannot load internal cache %s: error %s\n", cache_alg_name, err); |
| 85 | abort(); |
| 86 | } |
| 87 | |
| 88 | VERBOSE("internal cache %s loaded\n", cache_alg_name); |
| 89 | cache_t *cache = cache_init(cc_params, cache_specific_params); |
| 90 | return cache; |
| 91 | } |
| 92 | |
| 93 | cache_t *create_cache(const char *const cache_alg_name, |
| 94 | common_cache_params_t cc_params, void *specific_params) { |