static void signal_handler(int sig_num) { #ifdef WITH_THREAD #ifdef WITH_PTH if (PyThread_get_thread_ident() != main_thread) { pth_raise(*(pth_t *) main_thread, sig_num); return; } #endif /* See NOTES section above */ if (getpid() == main_pid) { #endif is_tripped++; Handlers[sig_num].tripped = 1; Py_AddPendingCall(checksignals_witharg, NULL); #ifdef WITH_THREAD } #endif #ifdef SIGCHLD if (sig_num == SIGCHLD) { /* To avoid infinite recursion, this signal remains reset until explicit re-instated. Don't clear the 'func' field as it is our pointer to the Python handler... */ return; } #endif #ifdef HAVE_SIGINTERRUPT siginterrupt(sig_num, 1); #endif PyOS_setsig(sig_num, signal_handler); }
/* 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; } }
/* Declared in pyerrors.h */ int PyErr_CheckSignals(void) { int i; PyObject *f; if (!is_tripped) return 0; #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) return 0; #endif if (!(f = (PyObject *)PyEval_GetFrame())) f = Py_None; for (i = 1; i < NSIG; i++) { if (Handlers[i].tripped) { PyObject *result = NULL; PyObject *arglist = Py_BuildValue("(iO)", i, f); Handlers[i].tripped = 0; if (arglist) { result = PyEval_CallObject(Handlers[i].func, arglist); Py_DECREF(arglist); } if (!result) return -1; Py_DECREF(result); } } is_tripped = 0; return 0; }
static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (_PyThreadState_GetFrame == NULL) _PyThreadState_GetFrame = threadstate_getframe; if (tstate != NULL) { tstate->interp = interp; tstate->frame = NULL; tstate->recursion_depth = 0; tstate->overflowed = 0; tstate->recursion_critical = 0; tstate->tracing = 0; tstate->use_tracing = 0; tstate->tick_counter = 0; tstate->gilstate_counter = 0; tstate->async_exc = NULL; #ifdef WITH_THREAD tstate->thread_id = PyThread_get_thread_ident(); #else tstate->thread_id = 0; #endif tstate->dict = NULL; tstate->curexc_type = NULL; tstate->curexc_value = NULL; tstate->curexc_traceback = NULL; tstate->exc_type = NULL; tstate->exc_value = NULL; tstate->exc_traceback = NULL; tstate->c_profilefunc = NULL; tstate->c_tracefunc = NULL; tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; tstate->trash_delete_nesting = 0; tstate->trash_delete_later = NULL; tstate->on_delete = NULL; tstate->on_delete_data = NULL; if (init) _PyThreadState_Init(tstate); HEAD_LOCK(); tstate->prev = NULL; tstate->next = interp->tstate_head; if (tstate->next) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); } return tstate; }
static PyObject * RLock_release(RLock *self, PyObject *args) { long tid = PyThread_get_thread_ident(); if (self->count == 0 || self->owner != tid) { PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock"); return NULL; } if (self->count > 1) { --self->count; Py_RETURN_NONE; } assert(self->count == 1); if (release_lock(&self->sem) != 0) return NULL; self->count = 0; self->owner = 0; Py_RETURN_NONE; }
static PyObject * RLock_acquire(RLock *self, PyObject *args, PyObject *kwds) { double timeout = -1; long tid; acquire_result res; if (parse_acquire_args(args, kwds, &timeout)) return NULL; tid = PyThread_get_thread_ident(); if (self->count > 0 && self->owner == tid) { unsigned long count = self->count + 1; if (count <= self->count) { PyErr_SetString(PyExc_OverflowError, "Internal lock count overflowed"); return NULL; } self->count = count; Py_RETURN_TRUE; } res = acquire_lock(&self->sem, timeout); if (res == ACQUIRE_ERROR) return NULL; if (res == ACQUIRE_OK) { assert(self->count == 0); self->owner = tid; self->count = 1; } return PyBool_FromLong(res == ACQUIRE_OK); }
void MPyEmbed_CBPostFrame(void) { int i; if (!PythonAvailable) { return; } PyThread_acquire_lock(threaddatalock, WAIT_LOCK); for (i = 0; i < THREADS; i++) { if (VALID(threaddata[i])) { PyObject *cb = threaddata[i].postframe; PyThreadState *ts = threaddata[i].mainstate; PyObject *rv; PyThread_release_lock(threaddatalock); ts->thread_id = PyThread_get_thread_ident(); PyEval_AcquireThread(ts); if (cb != NULL && PyCallable_Check(cb)) { rv = PyObject_CallObject(cb, NULL); Py_XDECREF(rv); if (rv == NULL) { PyErr_Print(); } } PyEval_ReleaseThread(ts); PyThread_acquire_lock(threaddatalock, WAIT_LOCK); } } PyThread_release_lock(threaddatalock); }
void update() { // This makes sense as an exception, but who knows how the user program would react // (it might swallow it and do something different) RELEASE_ASSERT(thread_id == PyThread_get_thread_ident(), "frame objects can only be accessed from the same thread"); PythonFrameIterator new_it = it.getCurrentVersion(); RELEASE_ASSERT(new_it.exists() && new_it.getFrameInfo()->frame_obj == this, "frame has exited"); it = std::move(new_it); }
void PyOS_AfterFork(void) { #ifdef WITH_THREAD PyEval_ReInitThreads(); main_thread = PyThread_get_thread_ident(); main_pid = getpid(); #endif }
int MPyEmbed_Repl(void) { if (!PythonAvailable) { return 0; } mainstate->thread_id = PyThread_get_thread_ident(); PyEval_AcquireThread(mainstate); PyRun_AnyFile(stdin, "<stdin>"); PyEval_ReleaseThread(mainstate); return 1; }
/* * Return the thread data for the current thread or NULL if it wasn't * recognised. */ static threadDef *currentThreadDef(void) { threadDef *thread; long ident = PyThread_get_thread_ident(); for (thread = threads; thread != NULL; thread = thread->next) if (thread->thr_ident == ident) break; return thread; }
static PyObject * thread_get_ident(PyObject *self) { long ident; ident = PyThread_get_thread_ident(); if (ident == -1) { PyErr_SetString(ThreadError, "no current thread ident"); return NULL; } return PyLong_FromLong(ident); }
PyThreadState * PyThreadState_New(PyInterpreterState *interp) { PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState)); if (_PyThreadState_GetFrame == NULL) _PyThreadState_GetFrame = threadstate_getframe; if (tstate != NULL) { tstate->interp = interp; tstate->frame = NULL; tstate->recursion_depth = 0; tstate->tracing = 0; tstate->use_tracing = 0; tstate->tick_counter = 0; tstate->gilstate_counter = 0; tstate->async_exc = NULL; #ifdef WITH_THREAD tstate->thread_id = PyThread_get_thread_ident(); #else tstate->thread_id = 0; #endif tstate->dict = NULL; tstate->curexc_type = NULL; tstate->curexc_value = NULL; tstate->curexc_traceback = NULL; tstate->exc_type = NULL; tstate->exc_value = NULL; tstate->exc_traceback = NULL; tstate->c_profilefunc = NULL; tstate->c_tracefunc = NULL; tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; #ifdef STACKLESS STACKLESS_PYSTATE_NEW; #endif #ifdef WITH_THREAD _PyGILState_NoteThreadState(tstate); #endif HEAD_LOCK(); tstate->next = interp->tstate_head; interp->tstate_head = tstate; HEAD_UNLOCK(); } return tstate; }
/* Declared in pyerrors.h */ int PyErr_CheckSignals(void) { int i; PyObject *f; if (!is_tripped) return 0; #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) return 0; #endif /* * The is_stripped variable is meant to speed up the calls to * PyErr_CheckSignals (both directly or via pending calls) when no * signal has arrived. This variable is set to 1 when a signal arrives * and it is set to 0 here, when we know some signals arrived. This way * we can run the registered handlers with no signals blocked. * * NOTE: with this approach we can have a situation where is_tripped is * 1 but we have no more signals to handle (Handlers[i].tripped * is 0 for every signal i). This won't do us any harm (except * we're gonna spent some cycles for nothing). This happens when * we receive a signal i after we zero is_tripped and before we * check Handlers[i].tripped. */ is_tripped = 0; if (!(f = (PyObject *)PyEval_GetFrame())) f = Py_None; for (i = 1; i < NSIG; i++) { if (Handlers[i].tripped) { PyObject *result = NULL; PyObject *arglist = Py_BuildValue("(iO)", i, f); Handlers[i].tripped = 0; if (arglist) { result = PyEval_CallObject(Handlers[i].func, arglist); Py_DECREF(arglist); } if (!result) return -1; Py_DECREF(result); } } return 0; }
void ProtectionData::lock() { long myThreadIdent = PyThread_get_thread_ident(); while(true) { PyScopedLock lock(mutex); if(lockCounter > 0 && lockThreadIdent != myThreadIdent) { usleep(10); continue; } lockCounter++; lockThreadIdent = myThreadIdent; return; } }
static PyObject * thread_get_ident(PyObject *self, PyObject *args) { long ident; if (!PyArg_NoArgs(args)) return NULL; ident = PyThread_get_thread_ident(); if (ident == -1) { PyErr_SetString(ThreadError, "no current thread ident"); return NULL; } return PyInt_FromLong(ident); }
int PyOS_InterruptOccurred(void) { if (Handlers[SIGINT].tripped) { #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) return 0; #endif Handlers[SIGINT].tripped = 0; return 1; } return 0; }
int MPyEmbed_Run(char *file) { FILE *fp; if (!PythonAvailable) { return 0; } fp = fopen(file, "r"); if (!fp) { perror("fopen"); return 0; } mainstate->thread_id = PyThread_get_thread_ident(); PyEval_AcquireThread(mainstate); PyRun_SimpleFile(fp, file); PyEval_ReleaseThread(mainstate); fclose(fp); return 1; }
static PyObject * signal_signal(PyObject *self, PyObject *args) { PyObject *obj; int sig_num; PyObject *old_handler; void (*func)(int); if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) return NULL; #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) { PyErr_SetString(PyExc_ValueError, "signal only works in main thread"); return NULL; } #endif if (sig_num < 1 || sig_num >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } if (obj == IgnoreHandler) func = SIG_IGN; else if (obj == DefaultHandler) func = SIG_DFL; else if (!PyCallable_Check(obj)) { PyErr_SetString(PyExc_TypeError, "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); return NULL; } else func = signal_handler; #ifdef HAVE_SIGINTERRUPT siginterrupt(sig_num, 1); #endif if (PyOS_setsig(sig_num, func) == SIG_ERR) { PyErr_SetFromErrno(PyExc_RuntimeError); return NULL; } old_handler = Handlers[sig_num].func; Handlers[sig_num].tripped = 0; Py_INCREF(obj); Handlers[sig_num].func = obj; return old_handler; }
static PyObject * Lock_acquire(Lock *self, PyObject *args, PyObject *kwds) { double timeout = -1; acquire_result res; if (parse_acquire_args(args, kwds, &timeout)) return NULL; res = acquire_lock(&self->sem, timeout); if (res == ACQUIRE_ERROR) return NULL; if (res == ACQUIRE_OK) self->owner = PyThread_get_thread_ident(); return PyBool_FromLong(res == ACQUIRE_OK); }
/* Internal helper. * If the current thread has a mapping for key, the appropriate struct key* * is returned. NB: value is ignored in this case! * If there is no mapping for key in the current thread, then: * If value is NULL, NULL is returned. * Else a mapping of key to value is created for the current thread, * and a pointer to a new struct key* is returned; except that if * malloc() can't find room for a new struct key*, NULL is returned. * So when value==NULL, this acts like a pure lookup routine, and when * value!=NULL, this acts like dict.setdefault(), returning an existing * mapping if one exists, else creating a new mapping. * * Caution: this used to be too clever, trying to hold keymutex only * around the "p->next = keyhead; keyhead = p" pair. That allowed * another thread to mutate the list, via key deletion, concurrent with * find_key() crawling over the list. Hilarity ensued. For example, when * the for-loop here does "p = p->next", p could end up pointing at a * record that PyThread_delete_key_value() was concurrently free()'ing. * That could lead to anything, from failing to find a key that exists, to * segfaults. Now we lock the whole routine. */ static struct key * find_key(int set_value, int key, void *value) { struct key *p, *prev_p; long id = PyThread_get_thread_ident(); if (!keymutex) return NULL; PyThread_acquire_lock(keymutex, 1); prev_p = NULL; for (p = keyhead; p != NULL; p = p->next) { if (p->id == id && p->key == key) { if (set_value) p->value = value; goto Done; } /* Sanity check. These states should never happen but if * they do we must abort. Otherwise we'll end up spinning * in a tight loop with the lock held. A similar check is done * in pystate.c tstate_delete_common(). */ if (p == prev_p) Py_FatalError("tls find_key: small circular list(!)"); prev_p = p; if (p->next == keyhead) Py_FatalError("tls find_key: circular list(!)"); } if (!set_value && value == NULL) { assert(p == NULL); goto Done; } p = (struct key *)PyMem_RawMalloc(sizeof(struct key)); if (p != NULL) { p->id = id; p->key = key; p->value = value; p->next = keyhead; keyhead = p; } Done: PyThread_release_lock(keymutex); return p; }
/* Forget the current thread's association for key, if any. */ void PyThread_delete_key_value(int key) { long id = PyThread_get_thread_ident(); struct key *p, **q; PyThread_acquire_lock(keymutex, 1); q = &keyhead; while ((p = *q) != NULL) { if (p->key == key && p->id == id) { *q = p->next; free((void *)p); /* NB This does *not* free p->value! */ break; } else q = &p->next; } PyThread_release_lock(keymutex); }
/* * Return the thread data for the current thread, allocating it if necessary, * or NULL if there was an error. */ static threadDef *currentThreadDef(int auto_alloc) { threadDef *thread, *empty = NULL; long ident = PyThread_get_thread_ident(); /* See if we already know about the thread. */ for (thread = threads; thread != NULL; thread = thread->next) { if (thread->thr_ident == ident) return thread; if (thread->thr_ident == 0) empty = thread; } if (!auto_alloc) { /* This is not an error. */ return NULL; } if (empty != NULL) { /* Use an empty entry in the list. */ thread = empty; } else if ((thread = sip_api_malloc(sizeof (threadDef))) == NULL) { return NULL; } else { thread->next = threads; threads = thread; } thread->thr_ident = ident; thread->pending.cpp = NULL; return thread; }
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(); }
/* * This is called from a newly created thread to initialise some thread local * storage. */ void sip_api_start_thread(void) { #ifdef WITH_THREAD threadDef *thread; /* Save the thread ID. First, find an empty slot in the list. */ for (thread = threads; thread != NULL; thread = thread->next) if (thread->thr_ident == 0) break; if (thread == NULL) { thread = sip_api_malloc(sizeof (threadDef)); thread->next = threads; threads = thread; } if (thread != NULL) { thread->thr_ident = PyThread_get_thread_ident(); thread->pending.cpp = NULL; } #endif }
int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; PyObject* database; int detect_types = 0; PyObject* isolation_level = NULL; PyObject* factory = NULL; int check_same_thread = 1; int cached_statements = 100; double timeout = 5.0; int rc; PyObject* database_utf8; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { return -1; } self->initialized = 1; self->begin_statement = NULL; self->statement_cache = NULL; self->statements = NULL; self->cursors = NULL; Py_INCREF(Py_None); self->row_factory = Py_None; Py_INCREF(&PyUnicode_Type); self->text_factory = (PyObject*)&PyUnicode_Type; if (PyString_Check(database) || PyUnicode_Check(database)) { if (PyString_Check(database)) { database_utf8 = database; Py_INCREF(database_utf8); } else { database_utf8 = PyUnicode_AsUTF8String(database); if (!database_utf8) { return -1; } } Py_BEGIN_ALLOW_THREADS rc = sqlite3_open(PyString_AsString(database_utf8), &self->db); Py_END_ALLOW_THREADS Py_DECREF(database_utf8); if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); return -1; } } else { PyErr_SetString(pysqlite_ProgrammingError, "Bad database parameter."); return -1; } if (!isolation_level) { isolation_level = PyString_FromString(""); if (!isolation_level) { return -1; } } else { Py_INCREF(isolation_level); } self->isolation_level = NULL; if (pysqlite_connection_set_isolation_level(self, isolation_level) < 0) { Py_DECREF(isolation_level); return -1; } Py_DECREF(isolation_level); self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } self->created_statements = 0; self->created_cursors = 0; /* Create lists of weak references to statements/cursors */ self->statements = PyList_New(0); self->cursors = PyList_New(0); if (!self->statements || !self->cursors) { return -1; } /* By default, the Cache class INCREFs the factory in its initializer, and * decrefs it in its deallocator method. Since this would create a circular * reference here, we're breaking it by decrementing self, and telling the * cache class to not decref the factory (self) in its deallocator. */ self->statement_cache->decref_factory = 0; Py_DECREF(self); self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); #ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); #endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); if (!self->function_pinboard) { return -1; } self->collations = PyDict_New(); if (!self->collations) { return -1; } self->Warning = pysqlite_Warning; self->Error = pysqlite_Error; self->InterfaceError = pysqlite_InterfaceError; self->DatabaseError = pysqlite_DatabaseError; self->DataError = pysqlite_DataError; self->OperationalError = pysqlite_OperationalError; self->IntegrityError = pysqlite_IntegrityError; self->InternalError = pysqlite_InternalError; self->ProgrammingError = pysqlite_ProgrammingError; self->NotSupportedError = pysqlite_NotSupportedError; return 0; }
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 pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; PyObject* database; int detect_types = 0; PyObject* isolation_level = NULL; PyObject* factory = NULL; int check_same_thread = 1; int cached_statements = 100; double timeout = 5.0; int rc; PyObject* class_attr = NULL; PyObject* class_attr_str = NULL; int is_apsw_connection = 0; PyObject* database_utf8; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { return -1; } self->begin_statement = NULL; self->statement_cache = NULL; self->statements = NULL; Py_INCREF(Py_None); self->row_factory = Py_None; Py_INCREF(&PyUnicode_Type); self->text_factory = (PyObject*)&PyUnicode_Type; if (PyString_Check(database) || PyUnicode_Check(database)) { if (PyString_Check(database)) { database_utf8 = database; Py_INCREF(database_utf8); } else { database_utf8 = PyUnicode_AsUTF8String(database); if (!database_utf8) { return -1; } } Py_BEGIN_ALLOW_THREADS rc = sqlite3_open(PyString_AsString(database_utf8), &self->db); Py_END_ALLOW_THREADS Py_DECREF(database_utf8); if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); return -1; } } else { /* Create a pysqlite connection from a APSW connection */ class_attr = PyObject_GetAttrString(database, "__class__"); if (class_attr) { class_attr_str = PyObject_Str(class_attr); if (class_attr_str) { if (strcmp(PyString_AsString(class_attr_str), "<type 'apsw.Connection'>") == 0) { /* In the APSW Connection object, the first entry after * PyObject_HEAD is the sqlite3* we want to get hold of. * Luckily, this is the same layout as we have in our * pysqlite_Connection */ self->db = ((pysqlite_Connection*)database)->db; Py_INCREF(database); self->apsw_connection = database; is_apsw_connection = 1; } } } Py_XDECREF(class_attr_str); Py_XDECREF(class_attr); if (!is_apsw_connection) { PyErr_SetString(PyExc_ValueError, "database parameter must be string or APSW Connection object"); return -1; } } if (!isolation_level) { isolation_level = PyString_FromString(""); if (!isolation_level) { return -1; } } else { Py_INCREF(isolation_level); } self->isolation_level = NULL; pysqlite_connection_set_isolation_level(self, isolation_level); Py_DECREF(isolation_level); self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } self->statements = PyList_New(0); if (!self->statements) { return -1; } self->created_statements = 0; /* By default, the Cache class INCREFs the factory in its initializer, and * decrefs it in its deallocator method. Since this would create a circular * reference here, we're breaking it by decrementing self, and telling the * cache class to not decref the factory (self) in its deallocator. */ self->statement_cache->decref_factory = 0; Py_DECREF(self); self->inTransaction = 0; self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); #ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); #endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); if (!self->function_pinboard) { return -1; } self->collations = PyDict_New(); if (!self->collations) { return -1; } self->Warning = pysqlite_Warning; self->Error = pysqlite_Error; self->InterfaceError = pysqlite_InterfaceError; self->DatabaseError = pysqlite_DatabaseError; self->DataError = pysqlite_DataError; self->OperationalError = pysqlite_OperationalError; self->IntegrityError = pysqlite_IntegrityError; self->InternalError = pysqlite_InternalError; self->ProgrammingError = pysqlite_ProgrammingError; self->NotSupportedError = pysqlite_NotSupportedError; return 0; }
static int floatsleep(double secs) { /* XXX Should test for MS_WINDOWS first! */ #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__) struct timeval t; double frac; frac = fmod(secs, 1.0); secs = floor(secs); t.tv_sec = (long)secs; t.tv_usec = (long)(frac*1000000.0); Py_BEGIN_ALLOW_THREADS if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { #ifdef EINTR if (errno != EINTR) { #else if (1) { #endif Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS #elif defined(__WATCOMC__) && !defined(__QNX__) /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ Py_END_ALLOW_THREADS #elif defined(MS_WINDOWS) { double millisecs = secs * 1000.0; unsigned long ul_millis; if (millisecs > (double)ULONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } Py_BEGIN_ALLOW_THREADS /* Allow sleep(0) to maintain win32 semantics, and as decreed * by Guido, only the main thread can be interrupted. */ ul_millis = (unsigned long)millisecs; if (ul_millis == 0 || main_thread != PyThread_get_thread_ident()) Sleep(ul_millis); else { DWORD rc; ResetEvent(hInterruptEvent); rc = WaitForSingleObject(hInterruptEvent, ul_millis); if (rc == WAIT_OBJECT_0) { /* Yield to make sure real Python signal * handler called. */ Sleep(1); Py_BLOCK_THREADS errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS } #elif defined(PYOS_OS2) /* This Sleep *IS* Interruptable by Exceptions */ Py_BEGIN_ALLOW_THREADS if (DosSleep(secs * 1000) != NO_ERROR) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS #elif defined(__BEOS__) /* This sleep *CAN BE* interrupted. */ { if( secs <= 0.0 ) { return; } Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) { Py_BLOCK_THREADS PyErr_SetFromErrno( PyExc_IOError ); return -1; } Py_END_ALLOW_THREADS } #elif defined(RISCOS) if (secs <= 0.0) return 0; Py_BEGIN_ALLOW_THREADS /* This sleep *CAN BE* interrupted. */ if ( riscos_sleep(secs) ) return -1; Py_END_ALLOW_THREADS #elif defined(PLAN9) { double millisecs = secs * 1000.0; if (millisecs > (double)LONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } /* This sleep *CAN BE* interrupted. */ Py_BEGIN_ALLOW_THREADS if(sleep((long)millisecs) < 0){ Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS } #else /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS sleep((int)secs); Py_END_ALLOW_THREADS #endif return 0; }
static int floatsleep(double secs) { /* XXX Should test for MS_WINDOWS first! */ #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__) struct timeval t; double frac; #if defined (AMITCP) || defined(INET225) /* check for availability of an Amiga TCP stack for select() */ if(!checksocketlib()) { /* no bsdsocket.library-- use dos/Delay() */ PyErr_Clear(); Delay((long)(secs*50)); /* XXX Can't interrupt this sleep */ return 0; } #endif frac = fmod(secs, 1.0); secs = floor(secs); t.tv_sec = (long)secs; t.tv_usec = (long)(frac*1000000.0); Py_BEGIN_ALLOW_THREADS if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { #ifdef EINTR if (errno != EINTR) { #else if (1) { #endif Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS #elif defined(macintosh) #define MacTicks (* (long *)0x16A) long deadline; deadline = MacTicks + (long)(secs * 60.0); while (MacTicks < deadline) { /* XXX Should call some yielding function here */ if (PyErr_CheckSignals()) return -1; } #elif defined(__WATCOMC__) && !defined(__QNX__) /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ Py_END_ALLOW_THREADS #elif defined(MS_WINDOWS) { double millisecs = secs * 1000.0; unsigned long ul_millis; if (millisecs > (double)ULONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } Py_BEGIN_ALLOW_THREADS /* Allow sleep(0) to maintain win32 semantics, and as decreed * by Guido, only the main thread can be interrupted. */ ul_millis = (unsigned long)millisecs; if (ul_millis == 0 || main_thread != PyThread_get_thread_ident()) Sleep(ul_millis); else { DWORD rc; ResetEvent(hInterruptEvent); rc = WaitForSingleObject(hInterruptEvent, ul_millis); if (rc == WAIT_OBJECT_0) { /* Yield to make sure real Python signal * handler called. */ Sleep(1); Py_BLOCK_THREADS errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS } #elif defined(PYOS_OS2) /* This Sleep *IS* Interruptable by Exceptions */ Py_BEGIN_ALLOW_THREADS if (DosSleep(secs * 1000) != NO_ERROR) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS #elif defined(__BEOS__) /* This sleep *CAN BE* interrupted. */ { if( secs <= 0.0 ) { return; } Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) { Py_BLOCK_THREADS PyErr_SetFromErrno( PyExc_IOError ); return -1; } Py_END_ALLOW_THREADS } #elif defined(RISCOS) if (secs <= 0.0) return 0; Py_BEGIN_ALLOW_THREADS /* This sleep *CAN BE* interrupted. */ if ( riscos_sleep(secs) ) return -1; Py_END_ALLOW_THREADS #elif defined(PLAN9) { double millisecs = secs * 1000.0; if (millisecs > (double)LONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } /* This sleep *CAN BE* interrupted. */ Py_BEGIN_ALLOW_THREADS if(sleep((long)millisecs) < 0){ Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS } #elif _AMIGA /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS Delay((long)(secs*50)); Py_END_ALLOW_THREADS #else /* !_AMIGA */ /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS sleep((int)secs); Py_END_ALLOW_THREADS #endif /* !_AMIGA */ /* XXX Can't interrupt this sleep */ return 0; }