|
40 | 40 |
|
41 | 41 | namespace py = pybind11;
|
42 | 42 |
|
| 43 | +template <typename T> void destroy_without_gil(T *ptr) { |
| 44 | + pybind11::gil_scoped_release nogil; |
| 45 | + delete ptr; |
| 46 | +} |
| 47 | + |
| 48 | +template <typename T> struct unique_ptr_nogil_deleter { |
| 49 | + void operator()(T *ptr) { destroy_without_gil(ptr); } |
| 50 | +}; |
| 51 | + |
43 | 52 | void bind_DNP3Manager(py::module &m)
|
44 | 53 | {
|
45 | 54 | // ----- class: asiodnp3::DNP3Manager -----
|
46 |
| - py::class_<asiodnp3::DNP3Manager, std::shared_ptr<asiodnp3::DNP3Manager>>(m, "DNP3Manager", |
| 55 | + py::class_<asiodnp3::DNP3Manager, |
| 56 | + std::unique_ptr<asiodnp3::DNP3Manager, |
| 57 | + unique_ptr_nogil_deleter< |
| 58 | + asiodnp3::DNP3Manager>>>(m, "DNP3Manager", |
47 | 59 | "Root DNP3 object used to create channels and sessions.")
|
48 | 60 |
|
49 | 61 | .def(
|
@@ -71,22 +83,11 @@ void bind_DNP3Manager(py::module &m)
|
71 | 83 | py::arg("concurrencyHint"), py::arg("handler"), py::arg("onThreadStart"), py::arg("onThreadExit")
|
72 | 84 | )
|
73 | 85 |
|
74 |
| - .def( |
75 |
| - "__del__", |
76 |
| - [](asiodnp3::DNP3Manager &self) |
77 |
| - { |
78 |
| - self.~DNP3Manager(); |
79 |
| - }, |
80 |
| - "Destructor with gil_scoped_release.", |
81 |
| - py::call_guard<py::gil_scoped_release>() |
82 |
| - ) |
83 |
| - |
84 | 86 | .def(
|
85 | 87 | "Shutdown",
|
86 | 88 | [](asiodnp3::DNP3Manager &self)
|
87 | 89 | {
|
88 | 90 | self.Shutdown();
|
89 |
| - self.~DNP3Manager(); |
90 | 91 | },
|
91 | 92 | "Permanently shutdown the manager and all sub-objects that have been created. Stop the thread pool.",
|
92 | 93 | py::call_guard<py::gil_scoped_release>()
|
|
0 commit comments