genesys: Add facility for auto releasing static data on backend exit

merge-requests/76/head
Povilas Kanapickas 2019-05-25 11:15:26 +03:00
rodzic 9cea33b53c
commit e5eff5d76f
3 zmienionych plików z 59 dodań i 0 usunięć

Wyświetl plik

@ -6453,6 +6453,8 @@ sane_exit_impl(void)
sanei_usb_exit();
run_functions_at_backend_exit();
DBGCOMPLETED;
}

Wyświetl plik

@ -2329,3 +2329,22 @@ void sanei_gl_vector_destroy(Genesys_Vector* v)
v->capacity = 0;
v->element_size = 0;
}
static std::unique_ptr<std::vector<std::function<void()>>> s_functions_run_at_backend_exit;
void add_function_to_run_at_backend_exit(std::function<void()> function)
{
if (!s_functions_run_at_backend_exit)
s_functions_run_at_backend_exit.reset(new std::vector<std::function<void()>>());
s_functions_run_at_backend_exit->push_back(std::move(function));
}
void run_functions_at_backend_exit()
{
for (auto it = s_functions_run_at_backend_exit->rbegin();
it != s_functions_run_at_backend_exit->rend(); ++it)
{
(*it)();
}
s_functions_run_at_backend_exit.release();
}

Wyświetl plik

@ -81,8 +81,12 @@
#include "../include/_stdint.h"
#include <algorithm>
#include <array>
#include <functional>
#include <memory>
#include <stdexcept>
#include <vector>
#define DBG_error0 0 /* errors/warnings printed even with devuglevel 0 */
#define DBG_error 1 /* fatal errors */
@ -1317,4 +1321,38 @@ inline void wrap_status_code_to_exception(SANE_Status status)
throw SaneException(status);
}
void add_function_to_run_at_backend_exit(std::function<void()> function);
// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being
// added.
void run_functions_at_backend_exit();
template<class T>
class StaticInit {
public:
StaticInit() = default;
StaticInit(const StaticInit&) = delete;
StaticInit& operator=(const StaticInit&) = delete;
template<class... Args>
void init(Args&& ... args)
{
ptr_ = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
add_function_to_run_at_backend_exit([this](){ deinit(); });
}
void deinit()
{
ptr_.release();
}
const T* operator->() const { return ptr_.get(); }
T* operator->() { return ptr_.get(); }
const T& operator*() const { return *ptr_.get(); }
T& operator*() { return *ptr_.get(); }
private:
std::unique_ptr<T> ptr_;
};
#endif /* not GENESYS_LOW_H */