void PyInterpreterState_Clear(PyInterpreterState *interp) { PyThreadState *p; HEAD_LOCK(); for (p = interp->tstate_head; p != NULL; p = p->next) PyThreadState_Clear(p); HEAD_UNLOCK(); _PyCoreConfig_Clear(&interp->core_config); _PyMainInterpreterConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); Py_CLEAR(interp->modules); Py_CLEAR(interp->modules_by_index); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); Py_CLEAR(interp->after_forkers_parent); Py_CLEAR(interp->after_forkers_child); #endif }
static int rw_close_th(SDL_RWops* context) { RWHelper* helper = (RWHelper*)context->hidden.unknown.data1; PyObject* result; int retval = 0; PyThreadState* oldstate; PyEval_AcquireLock(); oldstate = PyThreadState_Swap(helper->thread); if(helper->close) { result = PyObject_CallFunction(helper->close, NULL); if(result) retval = -1; Py_XDECREF(result); } PyThreadState_Swap(oldstate); PyThreadState_Clear(helper->thread); PyThreadState_Delete(helper->thread); Py_XDECREF(helper->seek); Py_XDECREF(helper->tell); Py_XDECREF(helper->write); Py_XDECREF(helper->read); Py_XDECREF(helper->close); PyMem_Del(helper); PyEval_ReleaseLock(); SDL_FreeRW(context); return retval; }
void PyInterpreterState_Clear(PyInterpreterState *interp) { PyThreadState *p; HEAD_LOCK(); for (p = interp->tstate_head; p != NULL; p = p->next) PyThreadState_Clear(p); HEAD_UNLOCK(); _PyCoreConfig_Clear(&interp->core_config); _PyMainInterpreterConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); Py_CLEAR(interp->modules); Py_CLEAR(interp->modules_by_index); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); Py_CLEAR(interp->after_forkers_parent); Py_CLEAR(interp->after_forkers_child); #endif // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's // objects have been cleaned up at the point. }
/** * z_policy_thread_destroy: * @self: this * * Destructor of ZPolicyThread. * The embedded Python thread context (self->thread) will be cleared and * deleted also, and if this thread was the last one running in the * interpreter instance, that will be stopped, too. */ void z_policy_thread_destroy(ZPolicyThread *self) { /* acquires the interpreter lock */ if (self->policy->main_thread != self) { /* we are one of the secondary threads */ z_python_lock(); PyThreadState_Swap(self->thread); PyThreadState_Clear(self->thread); PyThreadState_Swap(NULL); PyThreadState_Delete(self->thread); z_python_unlock(); z_policy_unref(self->policy); } else { /* we must be freed at last, when the policy is being destroyed */ g_assert(self->policy->ref_cnt == 1); /* we are the main thread, destroy the interpreter */ z_policy_purge(self->policy); PyEval_AcquireThread(self->thread); Py_EndInterpreter(self->thread); z_python_unlock(); } g_mutex_free(self->startable_lock); g_cond_free(self->startable_signal); g_free(self); }
/* * Delete all thread states except the one passed as argument. * Note that, if there is a current thread state, it *must* be the one * passed as argument. Also, this won't touch any other interpreters * than the current one, since we don't know which thread state should * be kept in those other interpreteres. */ void _PyThreadState_DeleteExcept(PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; PyThreadState *p, *next, *garbage; HEAD_LOCK(); /* Remove all thread states, except tstate, from the linked list of thread states. This will allow calling PyThreadState_Clear() without holding the lock. */ garbage = interp->tstate_head; if (garbage == tstate) garbage = tstate->next; if (tstate->prev) tstate->prev->next = tstate->next; if (tstate->next) tstate->next->prev = tstate->prev; tstate->prev = tstate->next = NULL; interp->tstate_head = tstate; HEAD_UNLOCK(); /* Clear and deallocate all stale thread states. Even if this executes Python code, we should be safe since it executes in the current thread, not one of the stale threads. */ for (p = garbage; p; p = next) { next = p->next; PyThreadState_Clear(p); PyMem_RawFree(p); } }
//------------------------------------------------------------------------------------- void Script::finiThread( bool plusOwnInterpreter ) { if( s_defaultContext != PyThreadState_Get() ) { KBE_EXIT( "trying to finalise script thread when not in default context" ); } if (plusOwnInterpreter) { { PyInterpreterState_Clear( s_defaultContext->interp ); PyThreadState_Swap( NULL ); PyInterpreterState_Delete( s_defaultContext->interp ); } PyEval_ReleaseLock(); } else { PyThreadState_Clear( s_defaultContext ); PyThreadState_DeleteCurrent(); // releases GIL } s_defaultContext = NULL; }
static void t_bootstrap(void *boot_raw) { struct bootstate *boot = (struct bootstate *) boot_raw; PyThreadState *tstate; PyObject *res; tstate = PyThreadState_New(boot->interp); PyEval_AcquireThread(tstate); res = PyEval_CallObjectWithKeywords( boot->func, boot->args, boot->keyw); Py_DECREF(boot->func); Py_DECREF(boot->args); Py_XDECREF(boot->keyw); PyMem_DEL(boot_raw); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) PyErr_Clear(); else { PySys_WriteStderr("Unhandled exception in thread:\n"); PyErr_PrintEx(0); } } else Py_DECREF(res); PyThreadState_Clear(tstate); PyThreadState_DeleteCurrent(); PyThread_exit_thread(); }
/** * Execute the current script * We are now in the thread. */ void PyApi::ExecuteInThread() const { assert(Py_IsInitialized() ); // get the lock so we can change things. PyEval_AcquireLock(); // make sure that the main thread is the active one. const auto mainInterpreterState = _mainThreadState->interp; PyThreadState_Swap(_mainThreadState); // create a new thread. const auto myThreadState = PyThreadState_New(mainInterpreterState); // make sure that the new thread has control // https://docs.python.org/3/c-api/init.html PyThreadState_Swap(myThreadState); // execute it... { const auto main_module = PyImport_AddModule("__main__"); const auto main_dict = PyModule_GetDict(main_module); Py_XINCREF(main_module); const auto local_dic = PyDict_New(); Py_XINCREF(local_dic); // we can now run our script const auto s = _script.c_str(); const auto pyRes = PyRun_String(s, Py_file_input, main_dict, local_dic); CheckForPythonErrors(); PyDict_Clear(local_dic); Py_XDECREF(local_dic); // pending calls must be cleared out Py_XDECREF(main_module); } // swap back to this thread. PyThreadState_Swap(myThreadState); // clear anything left behind. PyThreadState_Clear(myThreadState); PyThreadState_Swap(nullptr); // delete my thread. PyThreadState_Delete(myThreadState); // give control back to main thread PyThreadState_Swap(_mainThreadState); // release the lock one last time. PyEval_ReleaseLock(); }
PyThreadState * Py_NewInterpreter(void) { PyInterpreterState *interp; PyThreadState *tstate, *save_tstate; PyObject *bimod, *sysmod; if (!initialized) Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); interp = PyInterpreterState_New(); if (interp == NULL) return NULL; tstate = PyThreadState_New(interp); if (tstate == NULL) { PyInterpreterState_Delete(interp); return NULL; } save_tstate = PyThreadState_Swap(tstate); /* XXX The following is lax in error checking */ interp->modules = PyDict_New(); bimod = _PyImport_FindExtension("__builtin__", "__builtin__"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); Py_INCREF(interp->builtins); } sysmod = _PyImport_FindExtension("sys", "sys"); if (bimod != NULL && sysmod != NULL) { interp->sysdict = PyModule_GetDict(sysmod); Py_INCREF(interp->sysdict); PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); initmain(); if (!Py_NoSiteFlag) initsite(); } if (!PyErr_Occurred()) return tstate; /* Oops, it didn't work. Undo it all. */ PyErr_Print(); PyThreadState_Clear(tstate); PyThreadState_Swap(save_tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); return NULL; }
void End() { PyEval_AcquireLock(); PyThreadState_Swap( NULL ); PyThreadState_Clear( mainThreadState ); PyThreadState_Delete( mainThreadState ); //PyEval_Restore( mainThreadState ); Py_Finalize(); started = ScriptEngine::HasBegun(); }
PythonThreadState::~PythonThreadState() { if(m_thisThreadState) { PyThreadState_Swap(m_mainThreadState); PyThreadState_Clear(m_thisThreadState); PyThreadState_Delete(m_thisThreadState); PyEval_ReleaseLock(); } }
/** Cleanup any thread local storage on pthread_exit() */ static void do_python_cleanup(void *arg) { PyThreadState *my_thread_state = arg; PyEval_AcquireLock(); PyThreadState_Swap(NULL); /* Not entirely sure this is needed */ PyThreadState_Clear(my_thread_state); PyThreadState_Delete(my_thread_state); PyEval_ReleaseLock(); }
static PyObject * thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { PyObject *func, *args, *keyw = NULL; struct bootstate *boot; long ident; if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, &func, &args, &keyw)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "first arg must be callable"); return NULL; } if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "2nd arg must be a tuple"); return NULL; } if (keyw != NULL && !PyDict_Check(keyw)) { PyErr_SetString(PyExc_TypeError, "optional 3rd arg must be a dictionary"); return NULL; } boot = PyMem_NEW(struct bootstate, 1); if (boot == NULL) return PyErr_NoMemory(); boot->interp = PyThreadState_GET()->interp; boot->func = func; boot->args = args; boot->keyw = keyw; boot->tstate = _PyThreadState_Prealloc(boot->interp); if (boot->tstate == NULL) { PyMem_DEL(boot); return PyErr_NoMemory(); } Py_INCREF(func); Py_INCREF(args); Py_XINCREF(keyw); PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); if (ident == -1) { PyErr_SetString(ThreadError, "can't start new thread"); Py_DECREF(func); Py_DECREF(args); Py_XDECREF(keyw); PyThreadState_Clear(boot->tstate); PyMem_DEL(boot); return NULL; } return PyLong_FromLong(ident); }
void spyceClose() { if(spyInitialized) { PyEval_AcquireLock(); PyThreadState_Swap(NULL); PyThreadState_Clear(spyThreadState); PyThreadState_Delete(spyThreadState); PyEval_ReleaseLock(); g_pythonParser.Finalize(); } }
void pybase::FreeThreadState() { flext::thrid_t id = flext::GetThreadId(); PyThrMap::iterator it = pythrmap.find(id); if(it != pythrmap.end()) { // clear out any cruft from thread state object PyThreadState_Clear(it->second); // delete my thread state object PyThreadState_Delete(it->second); // delete from map pythrmap.erase(it); } }
void python_taskqueue::run( GLFWwindow *Context, rendertask_sequence &Tasks, threading::condition_variable &Condition, std::atomic<bool> &Exit ) { glfwMakeContextCurrent( Context ); // create a state object for this thread PyEval_AcquireLock(); auto *threadstate { PyThreadState_New( m_mainthread->interp ) }; PyEval_ReleaseLock(); render_task *task { nullptr }; while( false == Exit.load() ) { // regardless of the reason we woke up prime the spurious wakeup flag for the next time Condition.spurious( true ); // keep working as long as there's any scheduled tasks do { task = nullptr; // acquire a lock on the task queue and potentially grab a task from it { std::lock_guard<std::mutex> lock( Tasks.mutex ); if( false == Tasks.data.empty() ) { // fifo task = Tasks.data.front(); Tasks.data.pop_front(); } } if( task != nullptr ) { // swap in my thread state PyEval_RestoreThread( threadstate ); { // execute python code task->run(); error(); } // clear the thread state PyEval_SaveThread(); } // TBD, TODO: add some idle time between tasks in case we're on a single thread cpu? } while( task != nullptr ); // if there's nothing left to do wait until there is // but check every now and then on your own to minimize potential deadlock situations Condition.wait_for( std::chrono::seconds( 5 ) ); } // clean up thread state data PyEval_AcquireLock(); PyThreadState_Swap( nullptr ); PyThreadState_Clear( threadstate ); PyThreadState_Delete( threadstate ); PyEval_ReleaseLock(); }
void KviPythonInterpreter::done() { if(!m_pThreadState)return; // grab the lock PyEval_AcquireLock(); // swap my thread state out of the interpreter PyThreadState_Swap(NULL); // clear out any cruft from thread state object PyThreadState_Clear(m_pThreadState); // delete my thread state object PyThreadState_Delete(m_pThreadState); // release the lock PyEval_ReleaseLock(); m_pThreadState = 0; }
int PythonModule_Destroy( PythonModule* Self ) { if( Self != NULL ) { PyEval_AcquireLock(); PyThreadState_Swap(NULL); PyThreadState_Clear(Self->CurrentThreadState); PyThreadState_Delete(Self->CurrentThreadState); PyEval_ReleaseLock(); } free( Self ); }
void PyInterpreterState_Clear(PyInterpreterState *interp) { PyThreadState *p; HEAD_LOCK(); for (p = interp->tstate_head; p != NULL; p = p->next) PyThreadState_Clear(p); HEAD_UNLOCK(); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); Py_CLEAR(interp->modules); Py_CLEAR(interp->modules_reloading); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); }
gpointer pass_to_motor_v_multi_thread(gpointer args){ PyEval_AcquireLock(); PyInterpreterState * mainInterpreterState = mainThreadState->interp; PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState); PyThreadState_Swap(myThreadState); pass_to_motor(args); PyThreadState_Swap(NULL); PyThreadState_Clear(myThreadState); PyThreadState_Delete(myThreadState); PyEval_ReleaseLock(); return NULL; }
void interpreterFree(Interpreter *interpreter) { //PyEval_AcquireThread(interpreter->threadPythonState); //PyEval_RestoreThread(interpreter->threadPythonState); PyEval_RestoreThread(interpreter->threadPythonState); Py_DECREF(interpreter->pdict); //Py_EndInterpreter(interpreter->threadPythonState); PyThreadState_Clear(interpreter->threadPythonState); PyEval_SaveThread(); //PyEval_SaveThread(); //PyEval_ReleaseLock(); }
static void CPyStreamWrapper_Free (CPyStreamWrapper *wrapper) { if (!wrapper) { PyErr_SetString (PyExc_ValueError, "wrapper must not be NULL"); return; } #ifdef WITH_THREAD PyThreadState_Clear (wrapper->thread); PyThreadState_Delete (wrapper->thread); #endif Py_XDECREF (wrapper->seek); Py_XDECREF (wrapper->tell); Py_XDECREF (wrapper->write); Py_XDECREF (wrapper->read); Py_XDECREF (wrapper->close); PyMem_Free (wrapper); return; }
static int _pyobj_close_threaded (SDL_RWops *ops) { _RWWrapper *wrapper = (_RWWrapper *) ops->hidden.unknown.data1; PyObject *result; int retval = 0; PyThreadState* oldstate; PyThreadState* wrap; PyEval_AcquireThread (wrapper->thread); oldstate = PyThreadState_Swap (wrapper->thread); if (wrapper->close) { result = PyObject_CallFunction (wrapper->close, NULL); if (!result) { PyErr_Print (); retval = -1; } Py_XDECREF (result); } Py_XDECREF (wrapper->seek); Py_XDECREF (wrapper->tell); Py_XDECREF (wrapper->write); Py_XDECREF (wrapper->read); Py_XDECREF (wrapper->close); PyThreadState_Swap (oldstate); wrap = wrapper->thread; PyMem_Del (wrapper); PyThreadState_Clear (wrap); PyEval_ReleaseThread (wrap); PyThreadState_Delete (wrap); SDL_FreeRW (ops); return retval; }
static void t_bootstrap(void *boot_raw) { struct bootstate *boot = (struct bootstate *) boot_raw; PyThreadState *tstate; PyObject *res; tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); _PyThreadState_Init(tstate); PyEval_AcquireThread(tstate); res = PyEval_CallObjectWithKeywords( boot->func, boot->args, boot->keyw); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) PyErr_Clear(); else { PyObject *file; PySys_WriteStderr( "Unhandled exception in thread started by "); file = PySys_GetObject("stderr"); if (file != NULL && file != Py_None) PyFile_WriteObject(boot->func, file, 0); else PyObject_Print(boot->func, stderr, 0); PySys_WriteStderr("\n"); PyErr_PrintEx(0); } } else Py_DECREF(res); Py_DECREF(boot->func); Py_DECREF(boot->args); Py_XDECREF(boot->keyw); PyMem_DEL(boot_raw); PyThreadState_Clear(tstate); PyThreadState_DeleteCurrent(); PyThread_exit_thread(); }
void PyGILState_Release(PyGILState_STATE oldstate) { PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value( autoTLSkey); if (tcur == NULL) Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread"); /* We must hold the GIL and have our thread state current */ /* XXX - remove the check - the assert should be fine, but while this is very new (April 2003), the extra check by release-only users can't hurt. */ if (! PyThreadState_IsCurrent(tcur)) Py_FatalError("This thread state must be current when releasing"); assert(PyThreadState_IsCurrent(tcur)); --tcur->gilstate_counter; assert(tcur->gilstate_counter >= 0); /* illegal counter value */ /* If we're going to destroy this thread-state, we must * clear it while the GIL is held, as destructors may run. */ if (tcur->gilstate_counter == 0) { /* can't have been locked when we created it */ assert(oldstate == PyGILState_UNLOCKED); PyThreadState_Clear(tcur); /* Delete the thread-state. Note this releases the GIL too! * It's vital that the GIL be held here, to avoid shutdown * races; see bugs 225673 and 1061968 (that nasty bug has a * habit of coming back). */ PyThreadState_DeleteCurrent(); } /* Release the lock if necessary */ else if (oldstate == PyGILState_UNLOCKED) PyEval_SaveThread(); }
int MPyEmbed_RunThread(char *file) { int i; FILE *fp; if (!PythonAvailable) { return 0; } fp = fopen(file, "r"); if (!fp) { perror("fopen"); return 0; } PyThread_acquire_lock(threaddatalock, WAIT_LOCK); for (i = 0; i < THREADS; i++) { if (!VALID(threaddata[i])) { if (threaddata[i].exitlock != 0) PyThread_free_lock(threaddata[i].exitlock); threaddata[i].thread_id = PyThread_get_thread_ident(); PyEval_AcquireLock(); threaddata[i].threadstate = Py_NewInterpreter(); initpydega(); PySys_SetArgv(argc, argv); PyEval_ReleaseThread(threaddata[i].threadstate); threaddata[i].mainstate = PyThreadState_New(threaddata[i].threadstate->interp); threaddata[i].mainstate->thread_id = mainstate->thread_id; threaddata[i].exitlock = PyThread_allocate_lock(); PyThread_acquire_lock(threaddata[i].exitlock, WAIT_LOCK); break; } } PyThread_release_lock(threaddatalock); if (i == THREADS) { fclose(fp); return 0; } PyEval_AcquireThread(threaddata[i].threadstate); PyRun_SimpleFile(fp, file); PyEval_ReleaseThread(threaddata[i].threadstate); fclose(fp); PyThread_acquire_lock(threaddatalock, WAIT_LOCK); PyEval_AcquireThread(threaddata[i].threadstate); PyThread_release_lock(threaddatalock); Py_XDECREF(threaddata[i].postframe); PyThread_acquire_lock(threaddatalock, WAIT_LOCK); PyThreadState_Clear(threaddata[i].mainstate); PyThreadState_Delete(threaddata[i].mainstate); Py_EndInterpreter(threaddata[i].threadstate); PyEval_ReleaseLock(); threaddata[i].mainstate = threaddata[i].threadstate = 0; threaddata[i].postframe = 0; PyThread_release_lock(threaddatalock); PyThread_release_lock(threaddata[i].exitlock); return 1; }
PyThreadState * Py_NewInterpreter(void) { PyInterpreterState *interp; PyThreadState *tstate, *save_tstate; PyObject *bimod, *sysmod; if (!initialized) Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); #ifdef WITH_THREAD /* Issue #10915, #15751: The GIL API doesn't work with multiple interpreters: disable PyGILState_Check(). */ _PyGILState_check_enabled = 0; #endif interp = PyInterpreterState_New(); if (interp == NULL) return NULL; tstate = PyThreadState_New(interp); if (tstate == NULL) { PyInterpreterState_Delete(interp); return NULL; } save_tstate = PyThreadState_Swap(tstate); /* XXX The following is lax in error checking */ interp->modules = PyDict_New(); bimod = _PyImport_FindBuiltin("builtins"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) goto handle_error; Py_INCREF(interp->builtins); } /* initialize builtin exceptions */ _PyExc_Init(bimod); sysmod = _PyImport_FindBuiltin("sys"); if (bimod != NULL && sysmod != NULL) { PyObject *pstderr; interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) goto handle_error; Py_INCREF(interp->sysdict); PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); /* Set up a preliminary stderr printer until we have enough infrastructure for the io module in place. */ pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); _PySys_SetObjectId(&PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); _PyImportHooks_Init(); import_init(interp, sysmod); if (initfsencoding(interp) < 0) goto handle_error; if (initstdio() < 0) Py_FatalError( "Py_Initialize: can't initialize sys standard streams"); initmain(interp); if (!Py_NoSiteFlag) initsite(); } if (!PyErr_Occurred()) return tstate; handle_error: /* Oops, it didn't work. Undo it all. */ PyErr_PrintEx(0); PyThreadState_Clear(tstate); PyThreadState_Swap(save_tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); return NULL; }
static void eval_some_python(const char *funcname, char *args, switch_core_session_t *session, switch_stream_handle_t *stream, switch_event_t *params, char **str, struct switch_py_thread *pt) { PyThreadState *tstate = NULL; char *dupargs = NULL; char *argv[2] = { 0 }; int argc; char *script = NULL; PyObject *module = NULL, *sp = NULL, *stp = NULL, *eve = NULL; PyObject *function = NULL; PyObject *arg = NULL; PyObject *result = NULL; char *p; if (str) { *str = NULL; } if (args) { dupargs = strdup(args); } else { return; } assert(dupargs != NULL); if (!(argc = switch_separate_string(dupargs, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No module name specified!\n"); goto done; } script = strdup(switch_str_nil(argv[0])); if ((p = strstr(script, "::"))) { *p = '\0'; p += 2; if (p) { funcname = p; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Invoking py module: %s\n", script); tstate = PyThreadState_New(mainThreadState->interp); if (!tstate) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n"); goto done; } /* Save state in thread struct so we can terminate it later if needed */ if (pt) pt->tstate = tstate; // swap in thread state PyEval_AcquireThread(tstate); init_freeswitch(); // import the module module = PyImport_ImportModule((char *) script); if (!module) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n"); PyErr_Print(); PyErr_Clear(); goto done_swap_out; } // reload the module module = PyImport_ReloadModule(module); if (!module) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n"); PyErr_Print(); PyErr_Clear(); goto done_swap_out; } // get the handler function to be called function = PyObject_GetAttrString(module, (char *) funcname); if (!function) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define %s\n", funcname); PyErr_Print(); PyErr_Clear(); goto done_swap_out; } if (session) { sp = mod_python_conjure_session(module, session); } if (params) { eve = mod_python_conjure_event(params); } if (stream) { stp = mod_python_conjure_stream(stream); if (stream->param_event) { eve = mod_python_conjure_event(stream->param_event); } } if (sp && eve && stp) { arg = Py_BuildValue("(OOOs)", sp, stp, eve, switch_str_nil(argv[1])); } else if (eve && stp) { arg = Py_BuildValue("(sOOs)", "na", stp, eve, switch_str_nil(argv[1])); } else if (eve) { arg = Py_BuildValue("(Os)", eve, switch_str_nil(argv[1])); } else if (sp) { arg = Py_BuildValue("(Os)", sp, switch_str_nil(argv[1])); } else { arg = Py_BuildValue("(s)", switch_str_nil(argv[1])); } // invoke the handler switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call python script \n"); result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *) NULL); Py_DECREF(function); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Finished calling python script \n"); // check the result and print out any errors if (result) { if (str) { *str = strdup((char *) PyString_AsString(result)); } } else if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { // Print error, but ignore SystemExit switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n"); PyErr_Print(); PyErr_Clear(); PyRun_SimpleString("python_makes_sense"); PyGC_Collect(); } done_swap_out: if (arg) { Py_DECREF(arg); } if (sp) { Py_DECREF(sp); } if (tstate) { // thread state must be cleared explicitly or we'll get memory leaks PyThreadState_Clear(tstate); PyEval_ReleaseThread(tstate); PyThreadState_Delete(tstate); } done: switch_safe_free(dupargs); switch_safe_free(script); }
static rlm_rcode_t do_python(rlm_python_t *inst, REQUEST *request, PyObject *pFunc, char const *funcname, bool worker) { vp_cursor_t cursor; VALUE_PAIR *vp; PyObject *pRet = NULL; PyObject *pArgs = NULL; int tuplelen; int ret; PyGILState_STATE gstate; PyThreadState *prev_thread_state = NULL; /* -Wuninitialized */ memset(&gstate, 0, sizeof(gstate)); /* -Wuninitialized */ /* Return with "OK, continue" if the function is not defined. */ if (!pFunc) return RLM_MODULE_NOOP; #ifdef HAVE_PTHREAD_H gstate = PyGILState_Ensure(); if (worker) { PyThreadState *my_thread_state; my_thread_state = fr_thread_local_init(local_thread_state, do_python_cleanup); if (!my_thread_state) { my_thread_state = PyThreadState_New(inst->main_thread_state->interp); if (!my_thread_state) { REDEBUG("Failed initialising local PyThreadState on first run"); PyGILState_Release(gstate); return RLM_MODULE_FAIL; } ret = fr_thread_local_set(local_thread_state, my_thread_state); if (ret != 0) { REDEBUG("Failed storing PyThreadState in TLS: %s", fr_syserror(ret)); PyThreadState_Clear(my_thread_state); PyThreadState_Delete(my_thread_state); PyGILState_Release(gstate); return RLM_MODULE_FAIL; } } prev_thread_state = PyThreadState_Swap(my_thread_state); /* Swap in our local thread state */ } #endif /* Default return value is "OK, continue" */ ret = RLM_MODULE_OK; /* * We will pass a tuple containing (name, value) tuples * We can safely use the Python function to build up a * tuple, since the tuple is not used elsewhere. * * Determine the size of our tuple by walking through the packet. * If request is NULL, pass None. */ tuplelen = 0; if (request != NULL) { for (vp = paircursor(&cursor, &request->packet->vps); vp; vp = pairnext(&cursor)) { tuplelen++; } } if (tuplelen == 0) { Py_INCREF(Py_None); pArgs = Py_None; } else { int i = 0; if ((pArgs = PyTuple_New(tuplelen)) == NULL) { ret = RLM_MODULE_FAIL; goto finish; } for (vp = paircursor(&cursor, &request->packet->vps); vp; vp = pairnext(&cursor), i++) { PyObject *pPair; /* The inside tuple has two only: */ if ((pPair = PyTuple_New(2)) == NULL) { ret = RLM_MODULE_FAIL; goto finish; } if (mod_populate_vptuple(pPair, vp) == 0) { /* Put the tuple inside the container */ PyTuple_SET_ITEM(pArgs, i, pPair); } else { Py_INCREF(Py_None); PyTuple_SET_ITEM(pArgs, i, Py_None); Py_DECREF(pPair); } } } /* Call Python function. */ pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL); if (!pRet) { ret = RLM_MODULE_FAIL; goto finish; } if (!request) goto finish; /* * The function returns either: * 1. (returnvalue, replyTuple, configTuple), where * - returnvalue is one of the constants RLM_* * - replyTuple and configTuple are tuples of string * tuples of size 2 * * 2. the function return value alone * * 3. None - default return value is set * * xxx This code is messy! */ if (PyTuple_CheckExact(pRet)) { PyObject *pTupleInt; if (PyTuple_GET_SIZE(pRet) != 3) { ERROR("rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname); ret = RLM_MODULE_FAIL; goto finish; } pTupleInt = PyTuple_GET_ITEM(pRet, 0); if (!PyInt_CheckExact(pTupleInt)) { ERROR("rlm_python:%s: first tuple element not an integer", funcname); ret = RLM_MODULE_FAIL; goto finish; } /* Now have the return value */ ret = PyInt_AsLong(pTupleInt); /* Reply item tuple */ mod_vptuple(request->reply, &request->reply->vps, PyTuple_GET_ITEM(pRet, 1), funcname); /* Config item tuple */ mod_vptuple(request, &request->config_items, PyTuple_GET_ITEM(pRet, 2), funcname); } else if (PyInt_CheckExact(pRet)) { /* Just an integer */ ret = PyInt_AsLong(pRet); } else if (pRet == Py_None) { /* returned 'None', return value defaults to "OK, continue." */ ret = RLM_MODULE_OK; } else { /* Not tuple or None */ ERROR("rlm_python:%s: function did not return a tuple or None", funcname); ret = RLM_MODULE_FAIL; goto finish; } finish: if (pArgs) { Py_DECREF(pArgs); } if (pRet) { Py_DECREF(pRet); } #ifdef HAVE_PTHREAD_H if (worker) { PyThreadState_Swap(prev_thread_state); } PyGILState_Release(gstate); #endif return ret; }
void PyWinThreadState_Clear() { ThreadData *pData = (ThreadData *)TlsGetValue(dwTlsIndex); PyThreadState *thisThreadState = pData->ts; PyThreadState_Clear(thisThreadState); }