diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-10-09 13:39:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-09 13:39:51 (GMT) |
commit | 7bd560ce8de41e62230975c44fd7fbd189e8e858 (patch) | |
tree | 0d58bd28ecb0827591cf0c91a0a3cefc1de1926c /Python | |
parent | f4cb0d27cc08f490c42a22e646eb73cc7072d54a (diff) | |
download | cpython-7bd560ce8de41e62230975c44fd7fbd189e8e858.zip cpython-7bd560ce8de41e62230975c44fd7fbd189e8e858.tar.gz cpython-7bd560ce8de41e62230975c44fd7fbd189e8e858.tar.bz2 |
gh-76785: Add SendChannel.send_buffer() (#110246)
(This is still a test module.)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval_gil.c | 31 | ||||
-rw-r--r-- | Python/pystate.c | 43 |
2 files changed, 45 insertions, 29 deletions
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index f237e38..e269efa 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -663,7 +663,7 @@ _PyEval_SignalReceived(PyInterpreterState *interp) /* Push one item onto the queue while holding the lock. */ static int _push_pending_call(struct _pending_calls *pending, - _Py_pending_call_func func, void *arg) + _Py_pending_call_func func, void *arg, int flags) { int i = pending->last; int j = (i + 1) % NPENDINGCALLS; @@ -672,6 +672,7 @@ _push_pending_call(struct _pending_calls *pending, } pending->calls[i].func = func; pending->calls[i].arg = arg; + pending->calls[i].flags = flags; pending->last = j; assert(pending->calls_to_do < NPENDINGCALLS); pending->calls_to_do++; @@ -680,7 +681,7 @@ _push_pending_call(struct _pending_calls *pending, static int _next_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) + int (**func)(void *), void **arg, int *flags) { int i = pending->first; if (i == pending->last) { @@ -690,15 +691,16 @@ _next_pending_call(struct _pending_calls *pending, } *func = pending->calls[i].func; *arg = pending->calls[i].arg; + *flags = pending->calls[i].flags; return i; } /* Pop one item off the queue while holding the lock. */ static void _pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) + int (**func)(void *), void **arg, int *flags) { - int i = _next_pending_call(pending, func, arg); + int i = _next_pending_call(pending, func, arg, flags); if (i >= 0) { pending->calls[i] = (struct _pending_call){0}; pending->first = (i + 1) % NPENDINGCALLS; @@ -714,12 +716,12 @@ _pop_pending_call(struct _pending_calls *pending, int _PyEval_AddPendingCall(PyInterpreterState *interp, - _Py_pending_call_func func, void *arg, - int mainthreadonly) + _Py_pending_call_func func, void *arg, int flags) { - assert(!mainthreadonly || _Py_IsMainInterpreter(interp)); + assert(!(flags & _Py_PENDING_MAINTHREADONLY) + || _Py_IsMainInterpreter(interp)); struct _pending_calls *pending = &interp->ceval.pending; - if (mainthreadonly) { + if (flags & _Py_PENDING_MAINTHREADONLY) { /* The main thread only exists in the main interpreter. */ assert(_Py_IsMainInterpreter(interp)); pending = &_PyRuntime.ceval.pending_mainthread; @@ -729,7 +731,7 @@ _PyEval_AddPendingCall(PyInterpreterState *interp, assert(pending->lock != NULL); PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); + int result = _push_pending_call(pending, func, arg, flags); PyThread_release_lock(pending->lock); /* signal main loop */ @@ -743,7 +745,7 @@ Py_AddPendingCall(_Py_pending_call_func func, void *arg) /* Legacy users of this API will continue to target the main thread (of the main interpreter). */ PyInterpreterState *interp = _PyInterpreterState_Main(); - return _PyEval_AddPendingCall(interp, func, arg, 1); + return _PyEval_AddPendingCall(interp, func, arg, _Py_PENDING_MAINTHREADONLY); } static int @@ -769,17 +771,22 @@ _make_pending_calls(struct _pending_calls *pending) for (int i=0; i<NPENDINGCALLS; i++) { _Py_pending_call_func func = NULL; void *arg = NULL; + int flags = 0; /* pop one item off the queue while holding the lock */ PyThread_acquire_lock(pending->lock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); + _pop_pending_call(pending, &func, &arg, &flags); PyThread_release_lock(pending->lock); /* having released the lock, perform the callback */ if (func == NULL) { break; } - if (func(arg) != 0) { + int res = func(arg); + if ((flags & _Py_PENDING_RAWFREE) && arg != NULL) { + PyMem_RawFree(arg); + } + if (res != 0) { return -1; } } diff --git a/Python/pystate.c b/Python/pystate.c index 849a4ee..2086bd6 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -2584,18 +2584,36 @@ _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) return data->new_object(data); } -static int -_release_xidata_pending(void *data) +int +_Py_CallInInterpreter(PyInterpreterState *interp, + _Py_simple_func func, void *arg) { - _xidata_clear((_PyCrossInterpreterData *)data); + if (interp == current_fast_get(interp->runtime)->interp) { + return func(arg); + } + // XXX Emit a warning if this fails? + _PyEval_AddPendingCall(interp, (_Py_pending_call_func)func, arg, 0); + return 0; +} + +int +_Py_CallInInterpreterAndRawFree(PyInterpreterState *interp, + _Py_simple_func func, void *arg) +{ + if (interp == current_fast_get(interp->runtime)->interp) { + int res = func(arg); + PyMem_RawFree(arg); + return res; + } + // XXX Emit a warning if this fails? + _PyEval_AddPendingCall(interp, func, arg, _Py_PENDING_RAWFREE); return 0; } static int -_xidata_release_and_rawfree_pending(void *data) +_call_clear_xidata(void *data) { _xidata_clear((_PyCrossInterpreterData *)data); - PyMem_RawFree(data); return 0; } @@ -2627,21 +2645,12 @@ _xidata_release(_PyCrossInterpreterData *data, int rawfree) } // "Release" the data and/or the object. - if (interp == current_fast_get(interp->runtime)->interp) { - _xidata_clear(data); - if (rawfree) { - PyMem_RawFree(data); - } + if (rawfree) { + return _Py_CallInInterpreterAndRawFree(interp, _call_clear_xidata, data); } else { - _Py_pending_call_func func = _release_xidata_pending; - if (rawfree) { - func = _xidata_release_and_rawfree_pending; - } - // XXX Emit a warning if this fails? - _PyEval_AddPendingCall(interp, func, data, 0); + return _Py_CallInInterpreter(interp, _call_clear_xidata, data); } - return 0; } int |