diff options
author | Victor Stinner <vstinner@python.org> | 2023-08-23 22:19:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-23 22:19:11 (GMT) |
commit | 513c89d0122ff6245cfefbb49ef32bde8a2336f5 (patch) | |
tree | 4d2b87216c371ec4a2c7e318355698446e33295f /Modules/socketmodule.c | |
parent | b6be18812c68fce5ab56c266dc5fc5a3cceb09c0 (diff) | |
download | cpython-513c89d0122ff6245cfefbb49ef32bde8a2336f5.zip cpython-513c89d0122ff6245cfefbb49ef32bde8a2336f5.tar.gz cpython-513c89d0122ff6245cfefbb49ef32bde8a2336f5.tar.bz2 |
gh-108240: Add _PyCapsule_SetTraverse() internal function (#108339)
The _socket extension uses _PyCapsule_SetTraverse() to visit and clear
the socket type in the garbage collector. So the _socket.socket type
can be cleared in some corner cases when it wasn't possible before.
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index bb5edc3..392a56d 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -7314,20 +7314,39 @@ os_init(void) } #endif +static int +sock_capi_traverse(PyObject *capsule, visitproc visit, void *arg) +{ + PySocketModule_APIObject *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); + assert(capi != NULL); + Py_VISIT(capi->Sock_Type); + return 0; +} + +static int +sock_capi_clear(PyObject *capsule) +{ + PySocketModule_APIObject *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); + assert(capi != NULL); + Py_CLEAR(capi->Sock_Type); + return 0; +} + static void -sock_free_api(PySocketModule_APIObject *capi) +sock_capi_free(PySocketModule_APIObject *capi) { - Py_DECREF(capi->Sock_Type); + Py_XDECREF(capi->Sock_Type); // sock_capi_free() can clear it Py_DECREF(capi->error); Py_DECREF(capi->timeout_error); PyMem_Free(capi); } static void -sock_destroy_api(PyObject *capsule) +sock_capi_destroy(PyObject *capsule) { void *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); - sock_free_api(capi); + assert(capi != NULL); + sock_capi_free(capi); } static PySocketModule_APIObject * @@ -7432,11 +7451,17 @@ socket_exec(PyObject *m) } PyObject *capsule = PyCapsule_New(capi, PySocket_CAPSULE_NAME, - sock_destroy_api); + sock_capi_destroy); if (capsule == NULL) { - sock_free_api(capi); + sock_capi_free(capi); goto error; } + if (_PyCapsule_SetTraverse(capsule, + sock_capi_traverse, sock_capi_clear) < 0) { + sock_capi_free(capi); + goto error; + } + if (PyModule_Add(m, PySocket_CAPI_NAME, capsule) < 0) { goto error; } |