Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13 Add patch for python 3.13
193 lines
7.1 KiB
Diff
193 lines
7.1 KiB
Diff
diff -uNr a/core/init.c b/core/init.c
|
|
--- a/core/init.c 2024-06-01 20:40:38.000000000 +0200
|
|
+++ b/core/init.c 2024-08-13 09:56:13.152870522 +0200
|
|
@@ -432,8 +432,8 @@
|
|
uwsgi.cores = uwsgi.async;
|
|
}
|
|
|
|
+ uwsgi.has_threads = 1;
|
|
if (uwsgi.threads > 1) {
|
|
- uwsgi.has_threads = 1;
|
|
uwsgi.cores = uwsgi.threads;
|
|
}
|
|
|
|
diff -uNr a/core/uwsgi.c b/core/uwsgi.c
|
|
--- a/core/uwsgi.c 2024-06-01 20:40:38.000000000 +0200
|
|
+++ b/core/uwsgi.c 2024-08-13 09:56:13.156870522 +0200
|
|
@@ -197,7 +197,7 @@
|
|
{"freebind", no_argument, 0, "put socket in freebind mode", uwsgi_opt_true, &uwsgi.freebind, 0},
|
|
#endif
|
|
{"map-socket", required_argument, 0, "map sockets to specific workers", uwsgi_opt_add_string_list, &uwsgi.map_socket, 0},
|
|
- {"enable-threads", no_argument, 'T', "enable threads", uwsgi_opt_true, &uwsgi.has_threads, 0},
|
|
+ {"enable-threads", no_argument, 'T', "enable threads (stub option this is true by default)", uwsgi_opt_true, &uwsgi.has_threads, 0},
|
|
{"no-threads-wait", no_argument, 0, "do not wait for threads cancellation on quit/reload", uwsgi_opt_true, &uwsgi.no_threads_wait, 0},
|
|
|
|
{"auto-procname", no_argument, 0, "automatically set processes name to something meaningful", uwsgi_opt_true, &uwsgi.auto_procname, 0},
|
|
diff -uNr a/.github/workflows/test.yml b/.github/workflows/test.yml
|
|
--- a/.github/workflows/test.yml 2024-06-01 20:40:38.000000000 +0200
|
|
+++ b/.github/workflows/test.yml 2024-08-13 09:56:13.152870522 +0200
|
|
@@ -37,7 +37,7 @@
|
|
runs-on: ubuntu-20.04
|
|
strategy:
|
|
matrix:
|
|
- python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
|
+ python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
test-suite: [python, deadlocks]
|
|
steps:
|
|
- name: Add deadnakes ppa
|
|
diff -uNr a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c
|
|
--- a/plugins/python/python_plugin.c 2024-08-13 09:55:30.374870522 +0200
|
|
+++ b/plugins/python/python_plugin.c 2024-08-13 10:00:36.315870522 +0200
|
|
@@ -406,7 +406,7 @@
|
|
// reset python signal flags so child processes can trap signals
|
|
// Necessary if uwsgi fork hooks not called to update interpreter state
|
|
if (!up.call_uwsgi_fork_hooks && up.call_osafterfork) {
|
|
-#ifdef HAS_NOT_PyOS_AfterFork_Child
|
|
+#ifdef HAS_NOT_PYOS_FORK_STABLE_API
|
|
PyOS_AfterFork();
|
|
#else
|
|
PyOS_AfterFork_Child();
|
|
@@ -1340,11 +1340,10 @@
|
|
// Acquire the gil and import lock before forking in order to avoid
|
|
// deadlocks in workers
|
|
UWSGI_GET_GIL
|
|
-#if defined UWSGI_PY312
|
|
- PyInterpreterState *interp = PyInterpreterState_Get();
|
|
- _PyImport_AcquireLock(interp);
|
|
-#else
|
|
+#ifdef HAS_NOT_PYOS_FORK_STABLE_API
|
|
_PyImport_AcquireLock();
|
|
+#else
|
|
+ PyOS_BeforeFork();
|
|
#endif
|
|
}
|
|
}
|
|
@@ -1357,17 +1356,16 @@
|
|
if (uwsgi.has_threads) {
|
|
if (step == 0) {
|
|
// Release locks within master process
|
|
-#if defined UWSGI_PY312
|
|
- PyInterpreterState *interp = PyInterpreterState_Get();
|
|
- _PyImport_ReleaseLock(interp);
|
|
-#else
|
|
+#ifdef HAS_NOT_PYOS_FORK_STABLE_API
|
|
_PyImport_ReleaseLock();
|
|
+#else
|
|
+ PyOS_AfterFork_Parent();
|
|
#endif
|
|
UWSGI_RELEASE_GIL
|
|
}
|
|
else {
|
|
// Ensure thread state and locks are cleaned up in child process
|
|
-#ifdef HAS_NOT_PyOS_AfterFork_Child
|
|
+#ifdef HAS_NOT_PYOS_FORK_STABLE_API
|
|
PyOS_AfterFork();
|
|
#else
|
|
PyOS_AfterFork_Child();
|
|
@@ -1618,7 +1616,11 @@
|
|
PyGILState_Release(pgst);
|
|
|
|
if (wsgi_req) {
|
|
-#ifdef UWSGI_PY312
|
|
+#ifdef UWSGI_PY313
|
|
+ up.current_c_recursion_remaining[wsgi_req->async_id] = tstate->c_recursion_remaining;
|
|
+ up.current_py_recursion_remaining[wsgi_req->async_id] = tstate->py_recursion_remaining;
|
|
+ up.current_frame[wsgi_req->async_id] = tstate->current_frame;
|
|
+#elif defined UWSGI_PY312
|
|
up.current_c_recursion_remaining[wsgi_req->async_id] = tstate->c_recursion_remaining;
|
|
up.current_py_recursion_remaining[wsgi_req->async_id] = tstate->py_recursion_remaining;
|
|
up.current_frame[wsgi_req->async_id] = tstate->cframe;
|
|
@@ -1631,7 +1633,11 @@
|
|
#endif
|
|
}
|
|
else {
|
|
-#ifdef UWSGI_PY312
|
|
+#ifdef UWSGI_PY313
|
|
+ up.current_main_c_recursion_remaining = tstate->c_recursion_remaining;
|
|
+ up.current_main_py_recursion_remaining = tstate->py_recursion_remaining;
|
|
+ up.current_main_frame = tstate->current_frame;
|
|
+#elif defined UWSGI_PY312
|
|
up.current_main_c_recursion_remaining = tstate->c_recursion_remaining;
|
|
up.current_main_py_recursion_remaining = tstate->py_recursion_remaining;
|
|
up.current_main_frame = tstate->cframe;
|
|
@@ -1871,7 +1877,11 @@
|
|
PyGILState_Release(pgst);
|
|
|
|
if (wsgi_req) {
|
|
-#ifdef UWSGI_PY312
|
|
+#ifdef UWSGI_PY313
|
|
+ tstate->c_recursion_remaining = up.current_c_recursion_remaining[wsgi_req->async_id];
|
|
+ tstate->py_recursion_remaining = up.current_py_recursion_remaining[wsgi_req->async_id];
|
|
+ tstate->current_frame = up.current_frame[wsgi_req->async_id];
|
|
+#elif defined UWSGI_PY312
|
|
tstate->c_recursion_remaining = up.current_c_recursion_remaining[wsgi_req->async_id];
|
|
tstate->py_recursion_remaining = up.current_py_recursion_remaining[wsgi_req->async_id];
|
|
tstate->cframe = up.current_frame[wsgi_req->async_id];
|
|
@@ -1884,7 +1894,11 @@
|
|
#endif
|
|
}
|
|
else {
|
|
-#ifdef UWSGI_PY312
|
|
+#ifdef UWSGI_PY313
|
|
+ tstate->c_recursion_remaining = up.current_main_c_recursion_remaining;
|
|
+ tstate->py_recursion_remaining = up.current_main_py_recursion_remaining;
|
|
+ tstate->current_frame = up.current_main_frame;
|
|
+#elif defined UWSGI_PY312
|
|
tstate->c_recursion_remaining = up.current_main_c_recursion_remaining;
|
|
tstate->py_recursion_remaining = up.current_main_py_recursion_remaining;
|
|
tstate->cframe = up.current_main_frame;
|
|
@@ -2098,7 +2112,7 @@
|
|
// ensure signals can be used again from python
|
|
// Necessary if fork hooks have been not used to update interpreter state
|
|
if (!up.call_osafterfork && !up.call_uwsgi_fork_hooks)
|
|
-#ifdef HAS_NOT_PyOS_AfterFork_Child
|
|
+#ifdef HAS_NOT_PYOS_FORK_STABLE_API
|
|
PyOS_AfterFork();
|
|
#else
|
|
PyOS_AfterFork_Child();
|
|
diff -uNr a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h
|
|
--- a/plugins/python/uwsgi_python.h 2024-06-01 20:40:38.000000000 +0200
|
|
+++ b/plugins/python/uwsgi_python.h 2024-08-13 10:04:58.492870522 +0200
|
|
@@ -25,6 +25,10 @@
|
|
# define UWSGI_PY312
|
|
#endif
|
|
|
|
+#if (PY_VERSION_HEX >= 0x030d0000)
|
|
+# define UWSGI_PY313
|
|
+#endif
|
|
+
|
|
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
|
|
#define HAS_NOT_PyMemoryView_FromBuffer
|
|
#endif
|
|
@@ -41,12 +45,8 @@
|
|
#define HAS_NO_ERRORS_IN_PyFile_FromFd
|
|
#endif
|
|
|
|
-#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
|
|
-#define HAS_NOT_PyOS_AfterFork_Child
|
|
-#endif
|
|
-
|
|
-#if PY_MAJOR_VERSION < 3
|
|
-#define HAS_NOT_PyOS_AfterFork_Child
|
|
+#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7) || PY_MAJOR_VERSION < 3
|
|
+#define HAS_NOT_PYOS_FORK_STABLE_API
|
|
#endif
|
|
|
|
#if PY_MAJOR_VERSION > 2
|
|
@@ -172,7 +172,15 @@
|
|
|
|
char *callable;
|
|
|
|
-#ifdef UWSGI_PY312
|
|
+#ifdef UWSGI_PY313
|
|
+ int *current_c_recursion_remaining;
|
|
+ int *current_py_recursion_remaining;
|
|
+ struct _PyInterpreterFrame **current_frame;
|
|
+
|
|
+ int current_main_c_recursion_remaining;
|
|
+ int current_main_py_recursion_remaining;
|
|
+ struct _PyInterpreterFrame *current_main_frame;
|
|
+#elif defined UWSGI_PY312
|
|
int *current_c_recursion_remaining;
|
|
int *current_py_recursion_remaining;
|
|
_PyCFrame **current_frame;
|