1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 #include <dlfcn.h>
11 #include <memory>
12 
13 #include "cif/common/library_handle.h"
14 
15 namespace CIF {
16 
RAIIReleaseHelper(void * mod)17 void RAIIReleaseHelper(void * mod) noexcept {
18   if (nullptr == mod) {
19     return;
20   }
21   dlclose(mod);
22 }
23 
24 using UniquePtrLibrary_t = std::unique_ptr<void,
25                                            decltype(&RAIIReleaseHelper)>;
UniquePtrLibrary(void * mod)26 inline UniquePtrLibrary_t UniquePtrLibrary(void* mod) {
27   return UniquePtrLibrary_t(mod, &CIF::RAIIReleaseHelper);
28 }
29 
30 class LinLibraryHandle : public LibraryHandle {
31 public:
LinLibraryHandle(void * module,bool ownsHandle)32   LinLibraryHandle(void* module, bool ownsHandle)
33       : module(module), ownsHandle(ownsHandle) {}
~LinLibraryHandle()34   ~LinLibraryHandle() override {
35     if (ownsHandle && (nullptr != module)) {
36       dlclose(module);
37     }
38   }
GetFuncPointer(const std::string & funcName)39   void *GetFuncPointer(const std::string &funcName) const override {
40     if (module == nullptr) {
41       return nullptr;
42     }
43 
44     return dlsym(module, funcName.c_str());
45   }
46 
47 protected:
48   void* module;
49   bool ownsHandle;
50 };
51 
52 // open based on existing handle - takes ownership over handle
OpenLibrary(UniquePtrLibrary_t module)53 inline std::unique_ptr<LibraryHandle> OpenLibrary(UniquePtrLibrary_t module) {
54   std::unique_ptr<LibraryHandle> ret;
55   ret.reset(new LinLibraryHandle(module.release(), true));
56   return ret;
57 }
58 
59 // open based on existing handle - does not take ownership over handle
OpenLibrary(void * module)60 inline std::unique_ptr<LibraryHandle> OpenLibrary(void* module) {
61   std::unique_ptr<LibraryHandle> ret;
62   ret.reset(new LinLibraryHandle(module, false));
63   return ret;
64 }
65 }
66