static void _PyPathConfig_Clear(_PyPathConfig *config) { /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator, since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be called before Py_Initialize() which can changes the memory allocator. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); #define CLEAR(ATTR) \ do { \ PyMem_RawFree(ATTR); \ ATTR = NULL; \ } while (0) CLEAR(config->prefix); CLEAR(config->program_full_path); #ifdef MS_WINDOWS CLEAR(config->dll_path); #else CLEAR(config->exec_prefix); #endif CLEAR(config->module_search_path); CLEAR(config->home); CLEAR(config->program_name); #undef CLEAR PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); }
/* Reset the TSS key - called by PyOS_AfterFork_Child(). * This should not be necessary, but some - buggy - pthread implementations * don't reset TSS upon fork(), see issue #10517. */ void _PyGILState_Reinit(void) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyRuntime.interpreters.mutex = PyThread_allocate_lock(); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (_PyRuntime.interpreters.mutex == NULL) { Py_FatalError("Can't initialize threads for interpreter"); } PyThreadState *tstate = PyGILState_GetThisThreadState(); PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey); if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { Py_FatalError("Could not allocate TSS entry"); } /* If the thread had an associated auto thread state, reassociate it with * the new key. */ if (tstate && PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) != 0) { Py_FatalError("Couldn't create autoTSSkey mapping"); } }
/* Set the global path configuration from core_config. */ _PyInitError _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyInitError err; _PyPathConfig path_config = _PyPathConfig_INIT; path_config.module_search_path = wstrlist_join(DELIM, core_config->nmodule_search_path, core_config->module_search_paths); if (path_config.module_search_path == NULL) { goto no_memory; } if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) { goto no_memory; } if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) { goto no_memory; } #ifdef MS_WINDOWS if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) { goto no_memory; } #else if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) { goto no_memory; } #endif if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) { goto no_memory; } if (copy_wstr(&path_config.home, core_config->home) < 0) { goto no_memory; } err = _PyPathConfig_SetGlobal(&path_config); if (_Py_INIT_FAILED(err)) { goto done; } err = _Py_INIT_OK(); goto done; no_memory: err = _Py_INIT_NO_MEMORY(); done: _PyPathConfig_Clear(&path_config); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
_PyInitError _PyRuntimeState_Init(_PyRuntimeState *runtime) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyInitError err = _PyRuntimeState_Init_impl(runtime); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { /* Force the allocator used by _PyRuntimeState_Init(). */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (runtime->interpreters.mutex != NULL) { PyThread_free_lock(runtime->interpreters.mutex); runtime->interpreters.mutex = NULL; } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); }
void Py_SetProgramName(const wchar_t *program_name) { if (program_name == NULL || program_name[0] == L'\0') { return; } PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_RawFree(_Py_path_config.program_name); _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (_Py_path_config.program_name == NULL) { Py_FatalError("Py_SetProgramName() failed: out of memory"); } }
void Py_SetPythonHome(const wchar_t *home) { if (home == NULL) { return; } PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_RawFree(_Py_path_config.home); _Py_path_config.home = _PyMem_RawWcsdup(home); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (_Py_path_config.home == NULL) { Py_FatalError("Py_SetPythonHome() failed: out of memory"); } }
void Py_SetPath(const wchar_t *path) { if (path == NULL) { _PyPathConfig_Clear(&_Py_path_config); return; } PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyPathConfig new_config; new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName()); int alloc_error = (new_config.program_full_path == NULL); new_config.prefix = _PyMem_RawWcsdup(L""); alloc_error |= (new_config.prefix == NULL); #ifdef MS_WINDOWS new_config.dll_path = _PyMem_RawWcsdup(L""); alloc_error |= (new_config.dll_path == NULL); #else new_config.exec_prefix = _PyMem_RawWcsdup(L""); alloc_error |= (new_config.exec_prefix == NULL); #endif new_config.module_search_path = _PyMem_RawWcsdup(path); alloc_error |= (new_config.module_search_path == NULL); /* steal the home and program_name values (to leave them unchanged) */ new_config.home = _Py_path_config.home; _Py_path_config.home = NULL; new_config.program_name = _Py_path_config.program_name; _Py_path_config.program_name = NULL; _PyPathConfig_Clear(&_Py_path_config); _Py_path_config = new_config; PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (alloc_error) { Py_FatalError("Py_SetPath() failed: out of memory"); } }
/* Calculate the path configuration: initialize path_config from core_config */ static _PyInitError _PyPathConfig_Calculate(_PyPathConfig *path_config, const _PyCoreConfig *core_config) { _PyInitError err; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); /* Calculate program_full_path, prefix, exec_prefix (Unix) or dll_path (Windows), and module_search_path */ err = _PyPathConfig_Calculate_impl(&new_config, core_config); if (_Py_INIT_FAILED(err)) { goto err; } /* Copy home and program_name from core_config */ if (copy_wstr(&new_config.home, core_config->home) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } _PyPathConfig_Clear(path_config); *path_config = new_config; err = _Py_INIT_OK(); goto done; err: _PyPathConfig_Clear(&new_config); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
_PyInitError _PyPathConfig_SetGlobal(const _PyPathConfig *config) { _PyInitError err; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); #define COPY_ATTR(ATTR) \ do { \ if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \ _PyPathConfig_Clear(&new_config); \ err = _Py_INIT_NO_MEMORY(); \ goto done; \ } \ } while (0) COPY_ATTR(program_full_path); COPY_ATTR(prefix); #ifdef MS_WINDOWS COPY_ATTR(dll_path); #else COPY_ATTR(exec_prefix); #endif COPY_ATTR(module_search_path); COPY_ATTR(program_name); COPY_ATTR(home); _PyPathConfig_Clear(&_Py_path_config); /* Steal new_config strings; don't clear new_config */ _Py_path_config = new_config; err = _Py_INIT_OK(); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
_PyInitError _PyInterpreterState_Enable(_PyRuntimeState *runtime) { runtime->interpreters.next_id = 0; /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. Create a new mutex if needed. */ if (runtime->interpreters.mutex == NULL) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); runtime->interpreters.mutex = PyThread_allocate_lock(); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (runtime->interpreters.mutex == NULL) { return _Py_INIT_ERR("Can't initialize threads for interpreter"); } } return _Py_INIT_OK(); }