Skip to content

Commit a8910ca

Browse files
committed
Add custom deleter for plugin admissioner
1 parent a7ede08 commit a8910ca

File tree

1 file changed

+42
-36
lines changed

1 file changed

+42
-36
lines changed

src/export_admissioner.cpp

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,33 @@ pypluginAdmissioner_params {
3030
static bool pypluginAdmissioner_admit(admissioner_t *, const request_t *);
3131
static admissioner_t *pypluginAdmissioner_clone(admissioner_t *);
3232
static void pypluginAdmissioner_free(admissioner_t *);
33-
static void pypluginAdmissioner_update(admissioner_t *, const request_t *, const uint64_t);
33+
static void pypluginAdmissioner_update(admissioner_t *, const request_t *,
34+
const uint64_t);
35+
36+
struct PypluginAdmissionerParamsDeleter {
37+
void operator()(pypluginAdmissioner_params_t *ptr) const {
38+
if (ptr != nullptr) {
39+
if (!ptr->admissioner_free_hook.is_none()) {
40+
try {
41+
ptr->admissioner_free_hook(ptr->data);
42+
} catch (...) { }
43+
}
44+
delete ptr;
45+
}
46+
}
47+
};
3448

35-
// TODO: Free hook is currently not invoked at all, see export_cache.cpp and follow
36-
// their implementation pattern of using a custom deleter alongside std::unique_ptr
3749
admissioner_t *create_plugin_admissioner(std::string admissioner_name,
38-
py::function admissioner_init_hook,
39-
py::function admissioner_admit_hook,
40-
py::function admissioner_clone_hook,
41-
py::function admissioner_update_hook,
42-
py::function admissioner_free_hook) {
50+
py::function admissioner_init_hook,
51+
py::function admissioner_admit_hook,
52+
py::function admissioner_clone_hook,
53+
py::function admissioner_update_hook,
54+
py::function admissioner_free_hook) {
55+
std::unique_ptr<pypluginAdmissioner_params_t,
56+
PypluginAdmissionerParamsDeleter>
57+
params;
4358
admissioner_t *admissioner = nullptr;
44-
try{
59+
try {
4560
admissioner = (admissioner_t *)malloc(sizeof(admissioner_t));
4661
if (!admissioner) {
4762
throw std::runtime_error("Failed to initialize admissioner structure");
@@ -55,9 +70,9 @@ admissioner_t *create_plugin_admissioner(std::string admissioner_name,
5570
admissioner->update = pypluginAdmissioner_update;
5671

5772
// Initialize pointers to python hook functions
58-
std::unique_ptr<pypluginAdmissioner_params_t> params =
59-
std::make_unique<pypluginAdmissioner_params_t>(
60-
pypluginAdmissioner_params_t());
73+
params = std::unique_ptr<pypluginAdmissioner_params_t,
74+
PypluginAdmissionerParamsDeleter>(
75+
new pypluginAdmissioner_params_t(), PypluginAdmissionerParamsDeleter());
6176
params->data = admissioner_init_hook();
6277
params->admissioner_admit_hook = admissioner_admit_hook;
6378
params->admissioner_clone_hook = admissioner_clone_hook;
@@ -68,37 +83,36 @@ admissioner_t *create_plugin_admissioner(std::string admissioner_name,
6883
// Transfer ownership of params to admissioner
6984
admissioner->params = params.release();
7085
return admissioner;
71-
7286
} catch (...) {
73-
if (admissioner)
74-
free(admissioner);
87+
if (admissioner) free(admissioner);
7588
throw;
7689
}
7790
}
7891

79-
static bool pypluginAdmissioner_admit(admissioner_t *admissioner, const request_t *req) {
80-
pypluginAdmissioner_params_t* params =
81-
(pypluginAdmissioner_params_t*)admissioner->params;
92+
static bool pypluginAdmissioner_admit(admissioner_t *admissioner,
93+
const request_t *req) {
94+
pypluginAdmissioner_params_t *params =
95+
(pypluginAdmissioner_params_t *)admissioner->params;
8296
return params->admissioner_admit_hook(params->data, req).cast<bool>();
8397
}
8498

8599
static admissioner_t *pypluginAdmissioner_clone(admissioner_t *admissioner) {
86-
pypluginAdmissioner_params_t* params =
87-
(pypluginAdmissioner_params_t*)admissioner->params;
100+
pypluginAdmissioner_params_t *params =
101+
(pypluginAdmissioner_params_t *)admissioner->params;
88102
return params->admissioner_clone_hook(params->data).cast<admissioner_t *>();
89103
}
90104

91105
static void pypluginAdmissioner_free(admissioner_t *admissioner) {
92-
pypluginAdmissioner_params_t* params =
93-
(pypluginAdmissioner_params_t*)admissioner->params;
106+
pypluginAdmissioner_params_t *params =
107+
(pypluginAdmissioner_params_t *)admissioner->params;
94108
params->admissioner_free_hook(params->data);
95109
}
96110

97111
static void pypluginAdmissioner_update(admissioner_t *admissioner,
98112
const request_t *req,
99113
const uint64_t cache_size) {
100-
pypluginAdmissioner_params_t* params =
101-
(pypluginAdmissioner_params_t*)admissioner->params;
114+
pypluginAdmissioner_params_t *params =
115+
(pypluginAdmissioner_params_t *)admissioner->params;
102116
params->admissioner_update_hook(params->data, req, cache_size);
103117
}
104118

@@ -204,18 +218,10 @@ void export_admissioner(py::module &m) {
204218
m, "create_size_probabilistic_admissioner");
205219
export_admissioner_creator<create_adaptsize_admissioner>(
206220
m, "create_adaptsize_admissioner");
207-
208-
m.def(
209-
"create_plugin_admissioner",
210-
&create_plugin_admissioner,
211-
"admissioner_name",
212-
"admissioner_init_hook",
213-
"admissioner_admit_hook",
214-
"admissioner_clone_hook",
215-
"admissioner_update_hook",
216-
"admissioner_free_hook",
217-
py::return_value_policy::take_ownership
218-
);
221+
m.def("create_plugin_admissioner", &create_plugin_admissioner,
222+
"admissioner_name", "admissioner_init_hook", "admissioner_admit_hook",
223+
"admissioner_clone_hook", "admissioner_update_hook",
224+
"admissioner_free_hook", py::return_value_policy::take_ownership);
219225
}
220226

221227
} // namespace libcachesim

0 commit comments

Comments
 (0)