Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 38965ec

Browse filesBrowse files
authored
bpo-39947: Hide implementation detail of trashcan macros (GH-18971)
Py_TRASHCAN_BEGIN_CONDITION and Py_TRASHCAN_END macro no longer access PyThreadState attributes, but call new private _PyTrash_begin() and _PyTrash_end() functions which hide implementation details.
1 parent 309d7cc commit 38965ec
Copy full SHA for 38965ec

File tree

Expand file treeCollapse file tree

3 files changed

+45
-15
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+45
-15
lines changed

‎Include/cpython/object.h

Copy file name to clipboardExpand all lines: Include/cpython/object.h
+18-15Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,6 @@ PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
385385
*/
386386
PyAPI_DATA(int) _Py_SwappedOp[];
387387

388-
/* This is the old private API, invoked by the macros before 3.2.4.
389-
Kept for binary compatibility of extensions using the stable ABI. */
390-
PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*);
391-
PyAPI_FUNC(void) _PyTrash_destroy_chain(void);
392-
393388
PyAPI_FUNC(void)
394389
_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
395390
size_t sizeof_block);
@@ -507,10 +502,23 @@ partially-deallocated object. To check this, the tp_dealloc function must be
507502
passed as second argument to Py_TRASHCAN_BEGIN().
508503
*/
509504

510-
/* The new thread-safe private API, invoked by the macros below. */
505+
/* This is the old private API, invoked by the macros before 3.2.4.
506+
Kept for binary compatibility of extensions using the stable ABI. */
507+
PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*);
508+
PyAPI_FUNC(void) _PyTrash_destroy_chain(void);
509+
510+
/* This is the old private API, invoked by the macros before 3.9.
511+
Kept for binary compatibility of extensions using the stable ABI. */
511512
PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*);
512513
PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void);
513514

515+
/* Forward declarations for PyThreadState */
516+
struct _ts;
517+
518+
/* Python 3.9 private API, invoked by the macros below. */
519+
PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op);
520+
PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate);
521+
514522
#define PyTrash_UNWIND_LEVEL 50
515523

516524
#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
@@ -520,24 +528,19 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void);
520528
* is run normally without involving the trashcan */ \
521529
if (cond) { \
522530
_tstate = PyThreadState_GET(); \
523-
if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \
524-
/* Store the object (to be deallocated later) and jump past \
525-
* Py_TRASHCAN_END, skipping the body of the deallocator */ \
526-
_PyTrash_thread_deposit_object(_PyObject_CAST(op)); \
531+
if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
527532
break; \
528533
} \
529-
++_tstate->trash_delete_nesting; \
530534
}
531535
/* The body of the deallocator is here. */
532536
#define Py_TRASHCAN_END \
533537
if (_tstate) { \
534-
--_tstate->trash_delete_nesting; \
535-
if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \
536-
_PyTrash_thread_destroy_chain(); \
538+
_PyTrash_end(_tstate); \
537539
} \
538540
} while (0);
539541

540-
#define Py_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN_CONDITION(op, \
542+
#define Py_TRASHCAN_BEGIN(op, dealloc) \
543+
Py_TRASHCAN_BEGIN_CONDITION(op, \
541544
Py_TYPE(op)->tp_dealloc == (destructor)(dealloc))
542545

543546
/* For backwards compatibility, these macros enable the trashcan
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Py_TRASHCAN_BEGIN_CONDITION and Py_TRASHCAN_END macro no longer access
2+
PyThreadState attributes, but call new private _PyTrash_begin() and
3+
_PyTrash_end() functions which hide implementation details.

‎Objects/object.c

Copy file name to clipboardExpand all lines: Objects/object.c
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,30 @@ _PyTrash_thread_destroy_chain(void)
21162116
}
21172117

21182118

2119+
int
2120+
_PyTrash_begin(PyThreadState *tstate, PyObject *op)
2121+
{
2122+
if (tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) {
2123+
/* Store the object (to be deallocated later) and jump past
2124+
* Py_TRASHCAN_END, skipping the body of the deallocator */
2125+
_PyTrash_thread_deposit_object(op);
2126+
return 1;
2127+
}
2128+
++tstate->trash_delete_nesting;
2129+
return 0;
2130+
}
2131+
2132+
2133+
void
2134+
_PyTrash_end(PyThreadState *tstate)
2135+
{
2136+
--tstate->trash_delete_nesting;
2137+
if (tstate->trash_delete_later && tstate->trash_delete_nesting <= 0) {
2138+
_PyTrash_thread_destroy_chain();
2139+
}
2140+
}
2141+
2142+
21192143
void _Py_NO_RETURN
21202144
_PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg,
21212145
const char *file, int line, const char *function)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.