Пример #1
0
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();
}
Пример #2
0
/* 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");
    }
}
Пример #3
0
static int
allocate_barrier(barrierinfo *binfo)
{
  binfo->lock = PyThread_allocate_lock();
  binfo->n = 0;
  return (binfo->lock != NULL);
}
Пример #4
0
Файл: log.c Проект: yuriyao/PS
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
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;
    }
}
Пример #9
0
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;
}
Пример #10
0
static PyObject *
new_lock(void)
{
	PyThread_type_lock lock;

	lock = PyThread_allocate_lock();
	if (lock == NULL) return NULL;

	return PyCObject_FromVoidPtr(lock, destruct_lock);
}
Пример #11
0
/* 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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #18
0
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;
}
Пример #19
0
/*
 * 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 );
	}
}
Пример #20
0
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;
 }
Пример #21
0
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();
}
Пример #22
0
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 */
}
Пример #23
0
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;
}
Пример #24
0
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 {
Пример #25
0
_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();
}
Пример #26
0
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;
}
Пример #27
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;
}
Пример #28
0
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;
}
Пример #29
0
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;
}
Пример #30
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;
}