mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
use RAII in dispatcher to avoid refcount leaks in certain circumstances when handling exceptions
This commit is contained in:
parent
66c9a40213
commit
f4671f6a04
@ -227,20 +227,20 @@ private:
|
|||||||
*result = (PyObject *) 1;
|
*result = (PyObject *) 1;
|
||||||
try {
|
try {
|
||||||
for (; it != nullptr; it = it->next) {
|
for (; it != nullptr; it = it->next) {
|
||||||
PyObject *args_ = args;
|
object args_(args, true);
|
||||||
int kwargs_consumed = 0;
|
int kwargs_consumed = 0;
|
||||||
|
|
||||||
if (nargs < (int) it->args.size()) {
|
if (nargs < (int) it->args.size()) {
|
||||||
args_ = PyTuple_New(it->args.size());
|
args_ = object(PyTuple_New(it->args.size()), false);
|
||||||
for (int i = 0; i < nargs; ++i) {
|
for (int i = 0; i < nargs; ++i) {
|
||||||
PyObject *item = PyTuple_GET_ITEM(args, i);
|
PyObject *item = PyTuple_GET_ITEM(args, i);
|
||||||
Py_INCREF(item);
|
Py_INCREF(item);
|
||||||
PyTuple_SET_ITEM(args_, i, item);
|
PyTuple_SET_ITEM(args_.ptr(), i, item);
|
||||||
}
|
}
|
||||||
int arg_ctr = 0;
|
int arg_ctr = 0;
|
||||||
for (auto const &it2 : it->args) {
|
for (auto const &it2 : it->args) {
|
||||||
int index = arg_ctr++;
|
int index = arg_ctr++;
|
||||||
if (PyTuple_GET_ITEM(args_, index))
|
if (PyTuple_GET_ITEM(args_.ptr(), index))
|
||||||
continue;
|
continue;
|
||||||
PyObject *value = nullptr;
|
PyObject *value = nullptr;
|
||||||
if (kwargs)
|
if (kwargs)
|
||||||
@ -251,7 +251,7 @@ private:
|
|||||||
value = it2.value;
|
value = it2.value;
|
||||||
if (value) {
|
if (value) {
|
||||||
Py_INCREF(value);
|
Py_INCREF(value);
|
||||||
PyTuple_SET_ITEM(args_, index, value);
|
PyTuple_SET_ITEM(args_.ptr(), index, value);
|
||||||
} else {
|
} else {
|
||||||
kwargs_consumed = -1; /* definite failure */
|
kwargs_consumed = -1; /* definite failure */
|
||||||
break;
|
break;
|
||||||
@ -260,11 +260,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kwargs_consumed == nkwargs)
|
if (kwargs_consumed == nkwargs)
|
||||||
result = it->impl(it, args_, parent);
|
result = it->impl(it, args_.ptr(), parent);
|
||||||
|
|
||||||
if (args_ != args) {
|
|
||||||
Py_DECREF(args_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != (PyObject *) 1)
|
if (result != (PyObject *) 1)
|
||||||
break;
|
break;
|
||||||
@ -868,15 +864,13 @@ private:
|
|||||||
instance_type *inst = (instance_type *) inst_;
|
instance_type *inst = (instance_type *) inst_;
|
||||||
try {
|
try {
|
||||||
new (&inst->holder) holder_type(
|
new (&inst->holder) holder_type(
|
||||||
inst->value->shared_from_this()
|
inst->value->shared_from_this());
|
||||||
);
|
|
||||||
} catch (const std::bad_weak_ptr &) {
|
} catch (const std::bad_weak_ptr &) {
|
||||||
new (&inst->holder) holder_type(inst->value);
|
new (&inst->holder) holder_type(inst->value);
|
||||||
}
|
}
|
||||||
inst->constructed = true;
|
inst->constructed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dealloc(PyObject *inst_) {
|
static void dealloc(PyObject *inst_) {
|
||||||
instance_type *inst = (instance_type *) inst_;
|
instance_type *inst = (instance_type *) inst_;
|
||||||
if (inst->owned) {
|
if (inst->owned) {
|
||||||
|
Loading…
Reference in New Issue
Block a user