/** * 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); }
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; }
static void clRunPython(char* cmd) { #define BSZ 2048 char pyBuf[BSZ]; //clprintf (CL_LOG_SEV_INFO, "clRunPython called with [%s]", cmd); //clOsalMutexLock(&pyMutex); PyThreadState *tstate; //PyObject *result; snprintf(pyBuf,BSZ,"safplus.Callback(\"\"\"%s\"\"\")\n",cmd); //clprintf (CL_LOG_SEV_INFO, "clRunPython requesting python lock [%s]", cmd); /* interp is your reference to an interpreter object. */ tstate = PyThreadState_New(thePythonInterpreter); PyEval_AcquireThread(tstate); //clprintf(CL_LOG_SEV_INFO,"Stage 1. Passing to Python layer: %s",pyBuf); int ret = PyRun_SimpleString(pyBuf); //clprintf (CL_LOG_SEV_INFO, "clRunPython requesting release of python lock [%s]", cmd); PyEval_ReleaseThread(tstate); if (ret != 0) clprintf(CL_LOG_SEV_ERROR,"Ran: %s. There was an error.",pyBuf); PyThreadState_Delete(tstate); }
// Free the thread state for the current thread // (Presumably previously create with a call to // PyXPCOM_ThreadState_Ensure) void PyXPCOM_ThreadState_Free() { ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex); if (!pData) return; PyThreadState *thisThreadState = pData->ts; PyThreadState_Delete(thisThreadState); PR_SetThreadPrivate(tlsIndex, NULL); nsMemory::Free(pData); }
/** * 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(); }
// Free the thread state for the current thread // (Presumably previously create with a call to // PyWinThreadState_Ensure) void PyWinThreadState_Free() { ThreadData *pData = (ThreadData *)TlsGetValue(dwTlsIndex); if (!pData || !pData->owned) return; PyThreadState *thisThreadState = pData->ts; PyThreadState_Delete(thisThreadState); TlsSetValue(dwTlsIndex, NULL); LocalFree(pData); }
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; }
PythonThreadState::~PythonThreadState() { if(m_thisThreadState) { PyThreadState_Swap(m_mainThreadState); PyThreadState_Clear(m_thisThreadState); PyThreadState_Delete(m_thisThreadState); PyEval_ReleaseLock(); } }
static void zapthreads(PyInterpreterState *interp) { PyThreadState *p; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ while ((p = interp->tstate_head) != NULL) { PyThreadState_Delete(p); } }
void End() { PyEval_AcquireLock(); PyThreadState_Swap( NULL ); PyThreadState_Clear( mainThreadState ); PyThreadState_Delete( mainThreadState ); //PyEval_Restore( mainThreadState ); Py_Finalize(); started = ScriptEngine::HasBegun(); }
/** 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(); }
void spyceClose() { if(spyInitialized) { PyEval_AcquireLock(); PyThreadState_Swap(NULL); PyThreadState_Clear(spyThreadState); PyThreadState_Delete(spyThreadState); PyEval_ReleaseLock(); g_pythonParser.Finalize(); } }
void IvrPython::onDTMFEvent(int detectedKey) { dtmfKey.set(detectedKey); // wake up waiting functions... if (onDTMFCallback == NULL) { DBG("IvrPython::onDTMFEvent, but script did not set onDTMF callback!\n"); return; } DBG("IvrPython::onDTMFEvent(): calling onDTMFCallback key is %d...\n", detectedKey); #ifndef IVR_PERL PyThreadState *tstate; /* interp is your reference to an interpreter object. */ tstate = PyThreadState_New(mainInterpreterThreadState->interp); PyEval_AcquireThread(tstate); /* Perform Python actions here. */ PyObject *arglist = Py_BuildValue("(i)", detectedKey); PyObject *result = PyEval_CallObject(onDTMFCallback, arglist); Py_DECREF(arglist); if (result == NULL) { DBG("Calling IVR" SCRIPT_TYPE "onDTMF failed.\n"); PyErr_Print(); //return ; } else { Py_DECREF(result); } /* Release the thread. No Python API allowed beyond this point. */ PyEval_ReleaseThread(tstate); /* You can either delete the thread state, or save it until you need it the next time. */ PyThreadState_Delete(tstate); #else //IVR_PERL DBG("IvrPython::onDTMFEvent(): calling onDTMFCallback func is %s...\n", onDTMFCallback); PERL_SET_CONTEXT(my_perl_interp); DBG("context is %ld\n", (long) Perl_get_context()); dSP ; ENTER ; SAVETMPS ; PUSHMARK(SP) ; XPUSHs(sv_2mortal(newSViv(detectedKey))); PUTBACK ; call_pv(onDTMFCallback, G_DISCARD); FREETMPS ; LEAVE ; #endif //IVR_PERL DBG("IvrPython::onDTMFEvent done...\n"); }
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(); }
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 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; }
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 IvrPython::onMediaQueueEmpty() { isMediaQueueEmpty.set(true); DBG("executiong MQE callback...\n"); if (onMediaQueueEmptyCallback == NULL) { DBG("IvrPython::onMediaQueueEmpty, but script did not set onMediaQueueEmpty callback.\n"); return; } #ifndef IVR_PERL PyThreadState *tstate; /* interp is your reference to an interpreter object. */ tstate = PyThreadState_New(mainInterpreterThreadState->interp); PyEval_AcquireThread(tstate); /* Perform Python actions here. */ PyObject *arglist = Py_BuildValue("()"); PyObject *result = PyEval_CallObject(onMediaQueueEmptyCallback, arglist); Py_DECREF(arglist); if (result == NULL) { DBG("Calling IVR" SCRIPT_TYPE "onMediaQueueEmpty failed.\n"); // PyErr_Print(); //return ; } else { Py_DECREF(result); } /* Release the thread. No Python API allowed beyond this point. */ PyEval_ReleaseThread(tstate); /* You can either delete the thread state, or save it until you need it the next time. */ PyThreadState_Delete(tstate); #else //IVR_PERL PERL_SET_CONTEXT(my_perl_interp); DBG("context is %ld\n", (long) Perl_get_context()); dSP ; PUSHMARK(SP) ; call_pv(onMediaQueueEmptyCallback, G_DISCARD|G_NOARGS) ; #endif //IVR_PERL DBG("IvrPython::onMediaQueueEmpty done.\n"); }
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; }
void IvrPython::onBye(AmRequest* req) { if (onByeCallback == NULL) { DBG("Python script did not set onBye callback!\n"); return; } DBG("IvrPython::onBye(): calling onByeCallback ...\n"); #ifndef IVR_PERL PyThreadState *tstate; tstate = PyThreadState_New(mainInterpreterThreadState->interp); PyEval_AcquireThread(tstate); /* Perform Python actions here. */ PyObject *arglist = Py_BuildValue("()"); PyObject *result = PyEval_CallObject(onByeCallback, arglist); Py_DECREF(arglist); if (result == NULL) { DBG("Calling IVR" SCRIPT_TYPE "onMediaQueueEmpty failed.\n"); // PyErr_Print(); //return ; } else { Py_DECREF(result); } /* Release the thread. No Python API allowed beyond this point. */ PyEval_ReleaseThread(tstate); PyThreadState_Delete(tstate); #else //IVR_PERL PERL_SET_CONTEXT(my_perl_interp); DBG("context is %ld\n", (long) Perl_get_context()); dSP ; PUSHMARK(SP) ; call_pv(onByeCallback, G_DISCARD|G_NOARGS) ; #endif //IVR_PERL DBG("IvrPython::onBye done...\n"); }
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; }
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; }
int spyceRequest(webs_t wp, char_t *lpath) { // initialize python first if(!spyInitialized) { g_pythonParser.Initialize(); PyEval_AcquireLock(); PyInterpreterState * mainInterpreterState = g_pythonParser.getMainThreadState()->interp; spyThreadState = PyThreadState_New(mainInterpreterState); PyThreadState_Swap(spyThreadState); PyObject* pName = PyString_FromString("spyceXbmc"); PyObject* pModule = PyImport_Import(pName); Py_XDECREF(pName); if(!pModule) websError(wp, 500, (char*)"%s", (char*)"Corrupted Spyce installation"); else { PyObject* pDict = PyModule_GetDict(pModule); Py_XDECREF(pModule); spyFunc = PyDict_GetItemString(pDict, "ParseFile"); if(!spyFunc) websError(wp, 500, (char*)"%s", (char*)"Corrupted Spyce installation"); else spyInitialized = true; } PyThreadState_Swap(NULL); PyEval_ReleaseLock(); if(!spyInitialized) { PyThreadState_Clear(spyThreadState); PyThreadState_Delete(spyThreadState); g_pythonParser.Finalize(); return -1; } } PyEval_AcquireLock(); PyThreadState_Swap(spyThreadState); std::string strRequestMethod; std::string strQuery = wp->query; std::string strCookie; int iContentLength = 0; if (strlen(wp->query) > 0) { if(wp->flags & WEBS_POST_REQUEST) strRequestMethod = "POST"; else if (wp->flags & WEBS_HEAD_REQUEST) strRequestMethod = "HEAD"; else strRequestMethod = "GET"; } if (wp->flags & WEBS_COOKIE) strCookie = wp->cookie; iContentLength = strQuery.length(); // create enviroment and parse file PyObject* pEnv = PyDict_New(); PyObject* pREQUEST_METHOD = PyString_FromString(strRequestMethod.c_str()); PyObject* pCONTENT_LENGTH = PyInt_FromLong(iContentLength); PyObject* pQUERY_STRING = PyString_FromString(strQuery.c_str()); PyObject* pHTTP_COOKIE = PyString_FromString(strCookie.c_str()); PyObject* pCONTENT_TYPE = PyString_FromString(wp->type); PyObject* pHTTP_HOST = PyString_FromString(wp->host); PyObject* pHTTP_USER_AGENT = PyString_FromString(wp->userAgent ? wp->userAgent : ""); PyObject* pHTTP_CONNECTION = PyString_FromString((wp->flags & WEBS_KEEP_ALIVE)? "Keep-Alive" : ""); PyDict_SetItemString(pEnv, "REQUEST_METHOD", pREQUEST_METHOD); PyDict_SetItemString(pEnv, "CONTENT_LENGTH", pCONTENT_LENGTH); PyDict_SetItemString(pEnv, "QUERY_STRING", pQUERY_STRING); PyDict_SetItemString(pEnv, "HTTP_COOKIE", pHTTP_COOKIE); //PyDict_SetItemString(pEnv, "CONTENT_TYPE", pCONTENT_TYPE); PyDict_SetItemString(pEnv, "HTTP_HOST", pHTTP_HOST); PyDict_SetItemString(pEnv, "HTTP_USER_AGENT", pHTTP_USER_AGENT); PyDict_SetItemString(pEnv, "HTTP_CONNECTION", pHTTP_CONNECTION); PyObject* pResult = PyObject_CallFunction(spyFunc, (char*)"sO", lpath, pEnv); Py_XDECREF(pREQUEST_METHOD); Py_XDECREF(pCONTENT_LENGTH); Py_XDECREF(pQUERY_STRING); Py_XDECREF(pHTTP_COOKIE); Py_XDECREF(pCONTENT_TYPE); Py_XDECREF(pHTTP_HOST); Py_XDECREF(pHTTP_USER_AGENT); Py_XDECREF(pHTTP_CONNECTION); Py_XDECREF(pEnv); if(!pResult) websError(wp, 500, (char*)"%s", (char*)"Corrupted Spyce installation"); else { char* cResult = PyString_AsString(pResult); websWriteBlock(wp, cResult, strlen(cResult)); Py_XDECREF(pResult); } PyThreadState_Swap(NULL); PyEval_ReleaseLock(); /* * Common exit and cleanup */ if (websValid(wp)) { websPageClose(wp); } return 0; }
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 ThreadProc( void *data ) { PyObject *pName, *pModule, *pDict, *pFunc; PyThreadState *mainThreadState, *myThreadState, *tempState; PyInterpreterState *mainInterpreterState; CMD_LINE_STRUCT* arg = (CMD_LINE_STRUCT*)data; // Initialize python inerpreter Py_Initialize(); // Initialize thread support PyEval_InitThreads(); // Save a pointer to the main PyThreadState object mainThreadState = PyThreadState_Get(); // Get a reference to the PyInterpreterState mainInterpreterState = mainThreadState->interp; // Create a thread state object for this thread myThreadState = PyThreadState_New(mainInterpreterState); // Release global lock PyEval_ReleaseLock(); // Acquire global lock PyEval_AcquireLock(); // Swap in my thread state tempState = PyThreadState_Swap(myThreadState); // Now execute some python code (call python functions) pName = PyString_FromString(arg->argv[1]); pModule = PyImport_Import(pName); // pDict and pFunc are borrowed references pDict = PyModule_GetDict(pModule); pFunc = PyDict_GetItemString(pDict, arg->argv[2]); if (PyCallable_Check(pFunc)) { PyObject_CallObject(pFunc, NULL); } else { PyErr_Print(); } // Clean up Py_DECREF(pModule); Py_DECREF(pName); // Swap out the current thread PyThreadState_Swap(tempState); // Release global lock PyEval_ReleaseLock(); // Clean up thread state PyThreadState_Clear(myThreadState); PyThreadState_Delete(myThreadState); Py_Finalize(); printf("My thread is finishing...\n"); // Exiting the thread #ifdef WIN32 // Windows code _endthread(); #else // POSIX code pthread_exit(NULL); #endif }
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); }