diff options
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 93 |
1 files changed, 36 insertions, 57 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7187fe4..ce52990 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -154,8 +154,8 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) return 0; } -/* Global initializations. Can be undone by Py_FinalizeEx(). Don't - call this twice without an intervening Py_FinalizeEx() call. When +/* Global initializations. Can be undone by Py_Finalize(). Don't + call this twice without an intervening Py_Finalize() call. When initializations fail, a fatal error is issued and the function does not return. On return, the first thread and interpreter state have been created. @@ -223,8 +223,6 @@ get_locale_encoding(void) return NULL; } return get_codec_name(codeset); -#elif defined(__ANDROID__) - return get_codec_name("UTF-8"); #else PyErr_SetNone(PyExc_NotImplementedError); return NULL; @@ -329,11 +327,11 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) (void) PyThreadState_Swap(tstate); #ifdef WITH_THREAD - /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because + /* We can't call _PyEval_FiniThreads() in Py_Finalize because destroying the GIL might fail when it is being referenced from another running thread (see issue #9901). Instead we destroy the previously created GIL here, which ensures - that we can call Py_Initialize / Py_FinalizeEx multiple times. */ + that we can call Py_Initialize / Py_Finalize multiple times. */ _PyEval_FiniThreads(); /* Auto-thread-state API */ @@ -479,35 +477,28 @@ file_is_closed(PyObject *fobj) return r > 0; } -static int +static void flush_std_files(void) { PyObject *fout = _PySys_GetObjectId(&PyId_stdout); PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); PyObject *tmp; - int status = 0; if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); - if (tmp == NULL) { + if (tmp == NULL) PyErr_WriteUnraisable(fout); - status = -1; - } else Py_DECREF(tmp); } if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); - if (tmp == NULL) { + if (tmp == NULL) PyErr_Clear(); - status = -1; - } else Py_DECREF(tmp); } - - return status; } /* Undo the effect of Py_Initialize(). @@ -524,15 +515,14 @@ flush_std_files(void) */ -int -Py_FinalizeEx(void) +void +Py_Finalize(void) { PyInterpreterState *interp; PyThreadState *tstate; - int status = 0; if (!initialized) - return status; + return; wait_for_thread_shutdown(); @@ -557,9 +547,7 @@ Py_FinalizeEx(void) initialized = 0; /* Flush sys.stdout and sys.stderr */ - if (flush_std_files() < 0) { - status = -1; - } + flush_std_files(); /* Disable signal handling */ PyOS_FiniInterrupts(); @@ -588,9 +576,7 @@ Py_FinalizeEx(void) PyImport_Cleanup(); /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ - if (flush_std_files() < 0) { - status = -1; - } + flush_std_files(); /* Collect final garbage. This disposes of cycles created by * class definitions, for example. @@ -694,7 +680,6 @@ Py_FinalizeEx(void) /* Delete current thread. After this, many C API calls become crashy. */ PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); #ifdef Py_TRACE_REFS @@ -705,22 +690,12 @@ Py_FinalizeEx(void) if (Py_GETENV("PYTHONDUMPREFS")) _Py_PrintReferenceAddresses(stderr); #endif /* Py_TRACE_REFS */ -#ifdef WITH_PYMALLOC - if (_PyMem_PymallocEnabled()) { - char *opt = Py_GETENV("PYTHONMALLOCSTATS"); - if (opt != NULL && *opt != '\0') - _PyObject_DebugMallocStats(stderr); - } +#ifdef PYMALLOC_DEBUG + if (Py_GETENV("PYTHONMALLOCSTATS")) + _PyObject_DebugMallocStats(stderr); #endif call_ll_exitfuncs(); - return status; -} - -void -Py_Finalize(void) -{ - Py_FinalizeEx(); } /* Create and initialize a new interpreter and thread, and return the @@ -746,10 +721,6 @@ Py_NewInterpreter(void) if (!initialized) Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); - /* Issue #10915, #15751: The GIL API doesn't work with multiple - interpreters: disable PyGILState_Check(). */ - _PyGILState_check_enabled = 0; - interp = PyInterpreterState_New(); if (interp == NULL) return NULL; @@ -806,7 +777,7 @@ Py_NewInterpreter(void) if (initstdio() < 0) Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); + "Py_Initialize: can't initialize sys standard streams"); initmain(interp); if (!Py_NoSiteFlag) initsite(); @@ -832,7 +803,7 @@ handle_error: frames, and that it is its interpreter's only remaining thread. It is a fatal error to violate these constraints. - (Py_FinalizeEx() doesn't have these constraints -- it zaps + (Py_Finalize() doesn't have these constraints -- it zaps everything, regardless.) Locking: as above. @@ -1001,9 +972,6 @@ is_valid_fd(int fd) if (fd < 0 || !_PyVerify_fd(fd)) return 0; _Py_BEGIN_SUPPRESS_IPH - /* Prefer dup() over fstat(). fstat() can require input/output whereas - dup() doesn't, there is a low risk of EMFILE/ENFILE at Python - startup. */ fd2 = dup(fd); if (fd2 >= 0) close(fd2); @@ -1014,8 +982,8 @@ is_valid_fd(int fd) /* returns Py_None if the fd is not valid */ static PyObject* create_stdio(PyObject* io, - int fd, int write_mode, const char* name, - const char* encoding, const char* errors) + int fd, int write_mode, char* name, + char* encoding, char* errors) { PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; const char* mode; @@ -1045,8 +1013,7 @@ create_stdio(PyObject* io, mode = "rb"; buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", fd, mode, buffering, - Py_None, Py_None, /* encoding, errors */ - Py_None, 0); /* newline, closefd */ + Py_None, Py_None, Py_None, 0); if (buf == NULL) goto error; @@ -1276,11 +1243,25 @@ initstdio(void) static void _Py_FatalError_DumpTracebacks(int fd) { + PyThreadState *tstate; + +#ifdef WITH_THREAD + /* PyGILState_GetThisThreadState() works even if the GIL was released */ + tstate = PyGILState_GetThisThreadState(); +#else + tstate = PyThreadState_GET(); +#endif + if (tstate == NULL) { + /* _Py_DumpTracebackThreads() requires the thread state to display + * frames */ + return; + } + fputc('\n', stderr); fflush(stderr); /* display the current Python stack */ - _Py_DumpTracebackThreads(fd, NULL, NULL); + _Py_DumpTracebackThreads(fd, tstate->interp, tstate); } /* Print the current exception (if an exception is set) with its traceback, @@ -1481,9 +1462,7 @@ call_ll_exitfuncs(void) void Py_Exit(int sts) { - if (Py_FinalizeEx() < 0) { - sts = 120; - } + Py_Finalize(); exit(sts); } |