Skip to content

Commit 453783d

Browse files
committed
Some extra comments about the function_record ownership dance
1 parent 4511947 commit 453783d

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

include/pybind11/pybind11.h

+9
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class cpp_function : public function {
126126
struct capture { remove_reference_t<Func> f; };
127127

128128
/* Store the function including any extra state it might have (e.g. a lambda capture object) */
129+
// The unique_ptr makes sure nothing is leaked in case of an exception.
129130
auto unique_rec = make_function_record();
130131
auto rec = unique_rec.get();
131132

@@ -208,6 +209,7 @@ class cpp_function : public function {
208209
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
209210

210211
/* Register the function with Python from generic (non-templated) code */
212+
// Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.
211213
initialize_generic(std::move(unique_rec), signature.text, types.data(), sizeof...(Args));
212214

213215
if (cast_in::has_args) rec->has_args = true;
@@ -224,6 +226,8 @@ class cpp_function : public function {
224226
}
225227
}
226228

229+
// Utility class that keeps track of all duplicated strings, and cleans them up in its destructor,
230+
// unless they are released. Basically a RAII-solution to deal with exceptions along the way.
227231
class strdup_guard {
228232
public:
229233
~strdup_guard() {
@@ -247,6 +251,11 @@ class cpp_function : public function {
247251
const std::type_info *const *types, size_t args) {
248252
auto rec = unique_rec.get();
249253

254+
// Keep track of strdup'ed strings, and clean them up as long as the function's capsule
255+
// has not taken ownership yet (when `unique_rec.release()` is called).
256+
// Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the strings
257+
// are only referenced before strdup'ing. So only *after* the following block could `destruct`
258+
// safely be called, but even then, `repr` could still throw in the middle of copying all strings.
250259
strdup_guard guarded_strdup;
251260

252261
/* Create copies of all referenced C-style strings */

0 commit comments

Comments
 (0)