static _PyInitError _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) { memset(runtime, 0, sizeof(*runtime)); _PyGC_Initialize(&runtime->gc); _PyEval_Initialize(&runtime->ceval); runtime->gilstate.check_enabled = 1; /* A TSS key must be initialized with Py_tss_NEEDS_INIT in accordance with the specification. */ Py_tss_t initial = Py_tss_NEEDS_INIT; runtime->gilstate.autoTSSkey = initial; runtime->interpreters.mutex = PyThread_allocate_lock(); if (runtime->interpreters.mutex == NULL) { return _Py_INIT_ERR("Can't initialize threads for interpreter"); } runtime->interpreters.next_id = -1; runtime->xidregistry.mutex = PyThread_allocate_lock(); if (runtime->xidregistry.mutex == NULL) { return _Py_INIT_ERR("Can't initialize threads for cross-interpreter data registry"); } return _Py_INIT_OK(); }
/* 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"); } }
static int allocate_barrier(barrierinfo *binfo) { binfo->lock = PyThread_allocate_lock(); binfo->n = 0; return (binfo->lock != NULL); }
BOOL Ps_InitLog(FILE *normal, FILE *error, FILE *waring) { static int init = 0; //只能初始化一次 if(init) return TRUE; init = 1; #if LOG_LOCK_ENABLE log_lock = PyThread_allocate_lock(); if(!log_lock) { return FALSE; } #endif GET_LOG_LOCK(); log_normal = normal ? normal : stdout; log_error = error ? error : stderr; log_waring = waring ? waring : stdout; RELEASE_LOG_LOCK(); assert(log_waring); assert(log_error); assert(log_normal); return TRUE; }
static int _setup_ssl_threads(void) { unsigned int i; if (_ssl_locks == NULL) { _ssl_locks_count = CRYPTO_num_locks(); _ssl_locks = (PyThread_type_lock *) malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); if (_ssl_locks == NULL) return 0; memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); for (i = 0; i < _ssl_locks_count; i++) { _ssl_locks[i] = PyThread_allocate_lock(); if (_ssl_locks[i] == NULL) { unsigned int j; for (j = 0; j < i; j++) { PyThread_free_lock(_ssl_locks[j]); } free(_ssl_locks); return 0; } } CRYPTO_set_locking_callback(_ssl_thread_locking_function); CRYPTO_set_id_callback(_ssl_thread_id_function); } return 1; }
static PyObject * simplequeue_new_impl(PyTypeObject *type) /*[clinic end generated code: output=ba97740608ba31cd input=a0674a1643e3e2fb]*/ { simplequeueobject *self; self = (simplequeueobject *) type->tp_alloc(type, 0); if (self != NULL) { self->weakreflist = NULL; self->lst = PyList_New(0); self->lock = PyThread_allocate_lock(); self->lst_pos = 0; if (self->lock == NULL) { Py_DECREF(self); PyErr_SetString(PyExc_MemoryError, "can't allocate lock"); return NULL; } if (self->lst == NULL) { Py_DECREF(self); return NULL; } } return (PyObject *) self; }
static int test_bpo20891(void) { /* bpo-20891: Calling PyGILState_Ensure in a non-Python thread before calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must call PyEval_InitThreads() for us in this case. */ PyThread_type_lock lock = PyThread_allocate_lock(); if (!lock) { fprintf(stderr, "PyThread_allocate_lock failed!"); return 1; } _testembed_Py_Initialize(); unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock); if (thrd == PYTHREAD_INVALID_THREAD_ID) { fprintf(stderr, "PyThread_start_new_thread failed!"); return 1; } PyThread_acquire_lock(lock, WAIT_LOCK); Py_BEGIN_ALLOW_THREADS /* wait until the thread exit */ PyThread_acquire_lock(lock, WAIT_LOCK); Py_END_ALLOW_THREADS PyThread_free_lock(lock); return 0; }
/* Forget everything not associated with the current thread id. * This function is called from PyOS_AfterFork(). It is necessary * because other thread ids which were in use at the time of the fork * may be reused for new threads created in the forked process. */ void PyThread_ReInitTLS(void) { long id = PyThread_get_thread_ident(); struct key *p, **q; if (!keymutex) return; /* As with interpreter_lock in PyEval_ReInitThreads() we just create a new lock without freeing the old one */ keymutex = PyThread_allocate_lock(); /* Delete all keys which do not match the current thread id */ q = &keyhead; while ((p = *q) != NULL) { if (p->id != id) { *q = p->next; free((void *)p); /* NB This does *not* free p->value! */ } else q = &p->next; } }
static PyObject * newdbrnobject(char *file, int flags, int mode, int rnflags, int cachesize, int psize, int lorder, size_t reclen, u_char bval, char *bfname) { bsddbobject *dp; RECNOINFO info; int fd; if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = rnflags; info.cachesize = cachesize; info.psize = psize; info.lorder = lorder; info.reclen = reclen; info.bval = bval; info.bfname = bfname; #ifdef O_BINARY flags |= O_BINARY; #endif /* This is a hack to avoid a dbopen() bug that happens when * it fails. */ fd = open(file, flags); if (fd == -1) { dp->di_bsddb = NULL; } else { close(fd); Py_BEGIN_ALLOW_THREADS dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info); Py_END_ALLOW_THREADS } if (dp->di_bsddb == NULL) { PyErr_SetFromErrno(BsddbError); #ifdef WITH_THREAD dp->di_lock = NULL; #endif Py_DECREF(dp); return NULL; } dp->di_size = -1; dp->di_type = DB_RECNO; #ifdef WITH_THREAD dp->di_lock = PyThread_allocate_lock(); if (dp->di_lock == NULL) { PyErr_SetString(BsddbError, "can't allocate lock"); Py_DECREF(dp); return NULL; } #endif return (PyObject *)dp; }
static PyObject * new_lock(void) { PyThread_type_lock lock; lock = PyThread_allocate_lock(); if (lock == NULL) return NULL; return PyCObject_FromVoidPtr(lock, destruct_lock); }
/* Return a new key. This must be called before any other functions in * this family, and callers must arrange to serialize calls to this * function. No violations are detected. */ int PyThread_create_key(void) { /* All parts of this function are wrong if it's called by multiple * threads simultaneously. */ if (keymutex == NULL) keymutex = PyThread_allocate_lock(); return ++nkeys; }
char * PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { char *rv; if (_PyOS_ReadlineTState == PyThreadState_GET()) { PyErr_SetString(PyExc_RuntimeError, "can't re-enter readline"); return NULL; } if (PyOS_ReadlineFunctionPointer == NULL) { #ifdef __VMS PyOS_ReadlineFunctionPointer = vms__StdioReadline; #else PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; #endif } #ifdef WITH_THREAD if (_PyOS_ReadlineLock == NULL) { _PyOS_ReadlineLock = PyThread_allocate_lock(); } #endif _PyOS_ReadlineTState = PyThreadState_GET(); Py_BEGIN_ALLOW_THREADS #ifdef WITH_THREAD PyThread_acquire_lock(_PyOS_ReadlineLock, 1); #endif /* This is needed to handle the unlikely case that the * interpreter is in interactive mode *and* stdin/out are not * a tty. This can happen, for example if python is run like * this: python -i < test1.py */ if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout))) rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt); else rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt); Py_END_ALLOW_THREADS #ifdef WITH_THREAD PyThread_release_lock(_PyOS_ReadlineLock); #endif _PyOS_ReadlineTState = NULL; return rv; }
static int GPIO_set_callback(GPIO *self, PyObject *val, void *closure) { long ident; PyObject * tmp, *cb; struct poll_cb_info * poll_cb; cb = NULL; poll_cb = get_poll_cb(self->fd_val); if (poll_cb != NULL) cb = poll_cb->callback; if ( cb == val ) return 0; if ( cb != NULL ) { // printf("pre-del:\n"); // dump_poll_cb(); del_poll_cb(self->fd_val); // printf("post-del:\n"); // dump_poll_cb(); Py_DECREF( cb ); } if ( val == Py_None ) return 0; if ( !PyCallable_Check( val ) != 0 ) { PyErr_SetString(PyExc_TypeError, "set_callback: parameter must be a callable python object (function, method, class) or None"); return -1; } Py_INCREF(val); // printf("pre-add:\n"); // dump_poll_cb(); add_poll_cb(val, self->fd_val); // printf("post-add:\n"); // dump_poll_cb(); if (global_nfds == 1 && lock == NULL) { PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ interp = PyThreadState_Get()->interp; lock = PyThread_allocate_lock(); if (lock == NULL) return PyErr_NoMemory(); ident = PyThread_start_new_thread(t_bootstrap, (void*) self); if (ident == -1) { PyErr_SetString(PyExc_RuntimeError, "can't start new thread"); return -1; } } return 0; }
static PyObject * test_thread_state(PyObject *self, PyObject *args) { PyObject *fn; int success = 1; if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) return NULL; if (!PyCallable_Check(fn)) { PyErr_Format(PyExc_TypeError, "'%s' object is not callable", fn->ob_type->tp_name); return NULL; } /* Ensure Python is set up for threading */ PyEval_InitThreads(); thread_done = PyThread_allocate_lock(); if (thread_done == NULL) return PyErr_NoMemory(); PyThread_acquire_lock(thread_done, 1); /* Start a new thread with our callback. */ PyThread_start_new_thread(_make_call_from_thread, fn); /* Make the callback with the thread lock held by this thread */ success &= _make_call(fn); /* Do it all again, but this time with the thread-lock released */ Py_BEGIN_ALLOW_THREADS success &= _make_call(fn); PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ Py_END_ALLOW_THREADS /* And once more with and without a thread XXX - should use a lock and work out exactly what we are trying to test <wink> */ Py_BEGIN_ALLOW_THREADS PyThread_start_new_thread(_make_call_from_thread, fn); success &= _make_call(fn); PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ Py_END_ALLOW_THREADS /* Release lock we acquired above. This is required on HP-UX. */ PyThread_release_lock(thread_done); PyThread_free_lock(thread_done); if (!success) return NULL; Py_RETURN_NONE; }
static PyObject * newdbbtobject(char *file, int flags, int mode, int btflags, int cachesize, int maxkeypage, int minkeypage, int psize, int lorder) { bsddbobject *dp; BTREEINFO info; if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = btflags; info.cachesize = cachesize; info.maxkeypage = maxkeypage; info.minkeypage = minkeypage; info.psize = psize; info.lorder = lorder; info.compare = 0; /* Use default comparison functions, for now..*/ info.prefix = 0; #ifdef O_BINARY flags |= O_BINARY; #endif Py_BEGIN_ALLOW_THREADS dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info); Py_END_ALLOW_THREADS if (dp->di_bsddb == NULL) { PyErr_SetFromErrno(BsddbError); #ifdef WITH_THREAD dp->di_lock = NULL; #endif Py_DECREF(dp); return NULL; } dp->di_size = -1; dp->di_type = DB_BTREE; #ifdef WITH_THREAD dp->di_lock = PyThread_allocate_lock(); if (dp->di_lock == NULL) { PyErr_SetString(BsddbError, "can't allocate lock"); Py_DECREF(dp); return NULL; } #endif return (PyObject *)dp; }
int _PyInterpreterState_IDInitref(PyInterpreterState *interp) { if (interp->id_mutex != NULL) { return 0; } interp->id_mutex = PyThread_allocate_lock(); if (interp->id_mutex == NULL) { PyErr_SetString(PyExc_RuntimeError, "failed to create init interpreter ID mutex"); return -1; } interp->id_refcount = 0; return 0; }
static lockobject * newlockobject(void) { lockobject *self; self = PyObject_New(lockobject, &Locktype); if (self == NULL) return NULL; self->lock_lock = PyThread_allocate_lock(); if (self->lock_lock == NULL) { Py_DECREF(self); PyErr_SetString(ThreadError, "can't allocate lock"); return NULL; } return self; }
static PyObject * newdbhashobject(char *file, int flags, int mode, int bsize, int ffactor, int nelem, int cachesize, int hash, int lorder) { bsddbobject *dp; HASHINFO info; if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.bsize = bsize; info.ffactor = ffactor; info.nelem = nelem; info.cachesize = cachesize; info.hash = NULL; /* XXX should derive from hash argument */ info.lorder = lorder; #ifdef O_BINARY flags |= O_BINARY; #endif Py_BEGIN_ALLOW_THREADS dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info); Py_END_ALLOW_THREADS if (dp->di_bsddb == NULL) { PyErr_SetFromErrno(BsddbError); #ifdef WITH_THREAD dp->di_lock = NULL; #endif Py_DECREF(dp); return NULL; } dp->di_size = -1; dp->di_type = DB_HASH; #ifdef WITH_THREAD dp->di_lock = PyThread_allocate_lock(); if (dp->di_lock == NULL) { PyErr_SetString(BsddbError, "can't allocate lock"); Py_DECREF(dp); return NULL; } #endif return (PyObject *)dp; }
/* * Initialize our dictionary, and the dictionary mutex. */ static void beos_init_dyn( void ) { /* We're protected from a race condition here by the atomic init_count * variable. */ static int32 init_count = 0; int32 val; val = atomic_add( &init_count, 1 ); if( beos_dyn_images == NULL && val == 0 ) { beos_dyn_images = PyDict_New(); #ifdef WITH_THREAD beos_dyn_lock = PyThread_allocate_lock(); #endif atexit( beos_cleanup_dyn ); } }
static PyObject *CReader_Buffer_new(PyTypeObject *type, PyObject *args, PyObject *kws) { CReader_Buffer *self; uint maxsize = NEWREADER_BUFFER_MAXSIZE; PyObject *file; char *argnames[] = {"file", "maxsize", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kws, "O|I", argnames, &file, &maxsize)) return NULL; if (!(self = (CReader_Buffer *) type->tp_alloc(type, 0))) return NULL; # ifdef DEBUG_ALLOC fprintf(stderr, "Alloc: %p\n", (void *) self); # endif self->buf = NULL; self->pos = 0; self->len = 0; self->size = 0; self->maxsize = maxsize; self->type = CReader_BufferTypes; Py_INCREF(file); self->file = file; # ifdef WITH_THREAD self->state = NULL; self->lock = PyThread_allocate_lock(); # ifdef DEBUG_THREAD self->interplockings = 0; self->bufferlockings = 0; # endif # endif for (self->type = CReader_BufferTypes; self->type->init && !self->type->init(self); self->type++); if (!self->type->init) { PyErr_SetString(PyExc_TypeError, "Unsupported file-type"); Py_DECREF(self); return NULL; } PyErr_Clear(); # ifdef DEBUG_ALLOC fprintf(stderr, "Alloc done: %p\n", (void *) self); # endif return (PyObject *) self; }
void MPyEmbed_Init(void) { if (!PythonAvailable) { PythonAvailable = initlinkage(); } if (!PythonAvailable) { return; } PyEval_InitThreads(); Py_Initialize(); initpydega(); PySys_SetArgv(argc, argv); mainstate = PyEval_SaveThread(); memset(threaddata, 0, sizeof(threaddata)); threaddatalock = PyThread_allocate_lock(); }
PyMODINIT_FUNC PyInit_zlib(void) { PyObject *m, *ver; Comptype.ob_type = &PyType_Type; Decomptype.ob_type = &PyType_Type; m = Py_InitModule4("zlib", zlib_methods, zlib_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); if (m == NULL) return; ZlibError = PyErr_NewException("zlib.error", NULL, NULL); if (ZlibError != NULL) { Py_INCREF(ZlibError); PyModule_AddObject(m, "error", ZlibError); } PyModule_AddIntConstant(m, "MAX_WBITS", MAX_WBITS); PyModule_AddIntConstant(m, "DEFLATED", DEFLATED); PyModule_AddIntConstant(m, "DEF_MEM_LEVEL", DEF_MEM_LEVEL); PyModule_AddIntConstant(m, "Z_BEST_SPEED", Z_BEST_SPEED); PyModule_AddIntConstant(m, "Z_BEST_COMPRESSION", Z_BEST_COMPRESSION); PyModule_AddIntConstant(m, "Z_DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION); PyModule_AddIntConstant(m, "Z_FILTERED", Z_FILTERED); PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY); PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY); PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH); PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH); PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH); PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH); ver = PyString_FromString(ZLIB_VERSION); if (ver != NULL) PyModule_AddObject(m, "ZLIB_VERSION", ver); PyModule_AddStringConstant(m, "__version__", "1.0"); #ifdef WITH_THREAD zlib_lock = PyThread_allocate_lock(); #endif /* WITH_THREAD */ }
static compobject * newcompobject(PyTypeObject *type) { compobject *self; self = PyObject_New(compobject, type); if (self == NULL) return NULL; self->is_initialised = 0; self->unused_data = PyBytes_FromStringAndSize("", 0); if (self->unused_data == NULL) { Py_DECREF(self); return NULL; } self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); if (self->unconsumed_tail == NULL) { Py_DECREF(self); return NULL; } #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); #endif return self; }
static PyObject * EVP_update(EVPobject *self, PyObject *args) { PyObject *obj; Py_buffer view; if (!PyArg_ParseTuple(args, "O:update", &obj)) return NULL; GET_BUFFER_VIEW_OR_ERROUT(obj, &view); #ifdef WITH_THREAD if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { self->lock = PyThread_allocate_lock(); /* fail? lock = NULL and we fail over to non-threaded code. */ } if (self->lock != NULL) { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(self->lock, 1); EVP_hash(self, view.buf, view.len); PyThread_release_lock(self->lock); Py_END_ALLOW_THREADS } else {
_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(); }
PyInterpreterState * PyInterpreterState_New(void) { PyInterpreterState *interp = (PyInterpreterState *) PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp == NULL) { return NULL; } memset(interp, 0, sizeof(*interp)); interp->id_refcount = -1; interp->check_interval = 100; interp->ceval.pending.lock = PyThread_allocate_lock(); if (interp->ceval.pending.lock == NULL) { PyErr_SetString(PyExc_RuntimeError, "failed to create interpreter ceval pending mutex"); return NULL; } interp->core_config = _PyCoreConfig_INIT; interp->config = _PyMainInterpreterConfig_INIT; interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW interp->dlopenflags = RTLD_NOW; #else interp->dlopenflags = RTLD_LAZY; #endif #endif if (_PyRuntime.main_thread == 0) { _PyRuntime.main_thread = PyThread_get_thread_ident(); } HEAD_LOCK(); if (_PyRuntime.interpreters.next_id < 0) { /* overflow or Py_Initialize() not called! */ PyErr_SetString(PyExc_RuntimeError, "failed to get an interpreter ID"); PyMem_RawFree(interp); interp = NULL; } else { interp->id = _PyRuntime.interpreters.next_id; _PyRuntime.interpreters.next_id += 1; interp->next = _PyRuntime.interpreters.head; if (_PyRuntime.interpreters.main == NULL) { _PyRuntime.interpreters.main = interp; } _PyRuntime.interpreters.head = interp; } HEAD_UNLOCK(); if (interp == NULL) { return NULL; } interp->tstate_next_unique_id = 0; return interp; }
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; }
static PyObject *schedule_task_unblock(PyTaskletObject *prev, PyTaskletObject *next, int stackless) { PyThreadState *ts = PyThreadState_GET(); PyThreadState *nts = next->cstate->tstate; PyObject *retval; long thread_id = nts->thread_id; PyObject *unlock_lock; if (ts->st.thread.self_lock == NULL) { if (!(ts->st.thread.self_lock = new_lock())) return NULL; acquire_lock(ts->st.thread.self_lock, 1); if (!(ts->st.thread.unlock_lock = new_lock())) return NULL; if (interthread_lock == NULL) { if (!(interthread_lock = PyThread_allocate_lock())) return NULL; } } /* * make sure nobody else tries a transaction at the same time * on this tasklet's thread state, because two tasklets of the * same thread could be talking to different threads. They must * be serviced in fifo order. */ if (nts->st.thread.unlock_lock == NULL) { if (!(nts->st.thread.unlock_lock = new_lock())) return NULL; } unlock_lock = nts->st.thread.unlock_lock; Py_INCREF(unlock_lock); PyEval_SaveThread(); PR("unblocker waiting for unlocker lock"); acquire_lock(unlock_lock, 1); PR("unblocker HAS unlocker lock"); /* * also make sure that only one single interthread transaction * is performed at any time. */ PR("unblocker waiting for interthread lock"); PyThread_acquire_lock(interthread_lock, 1); PR("unblocker HAS interthread lock"); PyEval_RestoreThread(ts); /* get myself ready */ retval = slp_schedule_task(prev, prev, stackless); /* see whether the other thread still exists and is really blocked */ if (is_thread_alive(thread_id) && nts->st.thread.is_locked) { /* tell the blocker what comes next */ temp.unlock_target = next; temp.other_lock = ts->st.thread.self_lock; /* give it an extra ref, in case I would die early */ Py_INCREF(temp.other_lock); /* unblock it */ release_lock(nts->st.thread.self_lock); /* wait for the transaction to finish */ PyEval_SaveThread(); PR("unblocker waiting for own lock"); acquire_lock(ts->st.thread.self_lock, 1); PR("unblocker HAS own lock"); PyEval_RestoreThread(ts); } else { PR("unlocker: other is NOT LOCKED or dead"); if (next->flags.blocked) { /* unblock from channel */ slp_channel_remove_slow(next); slp_current_insert(next); } else if (next->next == NULL) { /* reactivate floating task */ Py_INCREF(next); slp_current_insert(next); } } PR("unblocker releasing interthread lock"); PyThread_release_lock(interthread_lock); PR("unblocker RELEASED interthread lock"); PR("unblocker releasing unlocker lock"); release_lock(unlock_lock); Py_DECREF(unlock_lock); PR("unblocker RELEASED unlocker lock"); return retval; }
static int Bucket__init__(pycbc_Bucket *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("connection_string", &create_opts.v.v3.connstr, "z") \ X("connstr", &create_opts.v.v3.connstr, "z") \ X("username", &create_opts.v.v3.username, "z") \ X("password", &create_opts.v.v3.passwd, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_flags", &self->flags, "I") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } create_opts.version = 3; create_opts.v.v3.type = conntype; if (iops_O && iops_O != Py_None) { self->iopswrap = pycbc_iowrap_new(self, iops_O); create_opts.v.v3.io = pycbc_iowrap_getiops(self->iopswrap); self->unlock_gil = 0; } if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(PYCBC_FMT_JSON); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Bucket_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Bucket_set_transcoder(self, tc, NULL) == -1) { return -1; } #if defined(WITH_THREAD) if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #else self->unlock_gil = 0; self->lockmode = PYCBC_LOCKMODE_NONE; #endif err = lcb_create(&self->instance, &create_opts); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } if (pycbc_log_handler) { err = lcb_cntl(self->instance, LCB_CNTL_SET, LCB_CNTL_LOGGER, &pycbc_lcb_logprocs); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create log handler"); return -1; } } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); { const char *bucketstr; err = lcb_cntl(self->instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bucketstr); if (err == LCB_SUCCESS && bucketstr != NULL) { self->bucket = pycbc_SimpleStringZ(bucketstr); } } return 0; }
static int Connection__init__(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; char *conncache = NULL; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *timeout = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; struct lcb_cached_config_st cached_config = { { 0 } }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("_errors", &self->errors, "O") \ X("_flags", &self->flags, "I") \ X("bucket", &create_opts.v.v1.bucket, "z") \ X("username", &create_opts.v.v1.user, "z") \ X("password", &create_opts.v.v1.passwd, "z") \ X("host", &create_opts.v.v1.host, "z") \ X("conncache", &conncache, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("timeout", &timeout, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } if (create_opts.v.v1.bucket) { self->bucket = pycbc_SimpleStringZ(create_opts.v.v1.bucket); } create_opts.version = 1; create_opts.v.v1.type = conntype; if (iops_O && iops_O != Py_None) { self->iops = pycbc_iops_new(self, iops_O); create_opts.v.v1.io = self->iops; self->unlock_gil = 0; } Py_INCREF(self->errors); if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(0); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Connection_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Connection_set_transcoder(self, tc, NULL) == -1) { return -1; } #ifdef WITH_THREAD if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #endif if (conncache) { if (conntype != LCB_TYPE_BUCKET) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Cannot use connection cache with " "management connection"); return -1; } cached_config.cachefile = conncache; memcpy(&cached_config.createopt, &create_opts, sizeof(create_opts)); err = lcb_create_compat(LCB_CACHED_CONFIG, &cached_config, &self->instance, NULL); } else { err = lcb_create(&self->instance, &create_opts); } if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); if (timeout && timeout != Py_None) { if (Connection_set_timeout(self, timeout, NULL) == -1) { return -1; } } PYCBC_CONN_THR_BEGIN(self); err = lcb_connect(self->instance); PYCBC_CONN_THR_END(self); if (err != LCB_SUCCESS) { PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't schedule connection. This might be a result of " "an invalid hostname."); return -1; } err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_WAIT(err); return -1; } return 0; }