예제 #1
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;
}
예제 #2
0
파일: _testembed.c 프로젝트: 1st1/cpython
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;
}
예제 #3
0
static PyObject*
faulthandler_dump_traceback_later(PyObject *self,
                                  PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
    double timeout;
    PY_TIMEOUT_T timeout_ms;
    int repeat = 0;
    PyObject *file = NULL;
    int fd;
    int exit = 0;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "d|iOi:dump_tracebacks_later", kwlist,
        &timeout, &repeat, &file, &exit))
        return NULL;
    timeout *= 1e6;
    if (timeout >= (double) PY_TIMEOUT_MAX) {
        PyErr_SetString(PyExc_OverflowError,  "timeout value is too large");
        return NULL;
    }
    timeout_ms = (PY_TIMEOUT_T)timeout;
    if (timeout_ms <= 0) {
        PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
        return NULL;
    }

    file = faulthandler_get_fileno(file, &fd);
    if (file == NULL)
        return NULL;

    /* Cancel previous thread, if running */
    faulthandler_cancel_dump_tracebacks_later();

    Py_XDECREF(thread.file);
    Py_INCREF(file);
    thread.file = file;
    thread.fd = fd;
    thread.timeout_ms = timeout_ms;
    thread.repeat = repeat;
    thread.interp = PyThreadState_Get()->interp;
    thread.exit = exit;

    /* Arm these locks to serve as events when released */
    PyThread_acquire_lock(thread.join_event, 1);
    PyThread_acquire_lock(thread.cancel_event, 1);

    thread.running = 1;
    if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
        thread.running = 0;
        PyThread_release_lock(thread.join_event);
        PyThread_release_lock(thread.cancel_event);
        Py_CLEAR(thread.file);
        PyErr_SetString(PyExc_RuntimeError,
                        "unable to start watchdog thread");
        return NULL;
    }

    Py_RETURN_NONE;
}
static PyObject *
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
{
	PyObject *func, *args, *keyw = NULL;
	struct bootstate *boot;
	long ident;

	if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
		               &func, &args, &keyw))
		return NULL;
	if (!PyCallable_Check(func)) {
		PyErr_SetString(PyExc_TypeError,
				"first arg must be callable");
		return NULL;
	}
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_TypeError,
				"2nd arg must be a tuple");
		return NULL;
	}
	if (keyw != NULL && !PyDict_Check(keyw)) {
		PyErr_SetString(PyExc_TypeError,
				"optional 3rd arg must be a dictionary");
		return NULL;
	}
	boot = PyMem_NEW(struct bootstate, 1);
	if (boot == NULL)
		return PyErr_NoMemory();
	boot->interp = PyThreadState_GET()->interp;
	boot->func = func;
	boot->args = args;
	boot->keyw = keyw;
	boot->tstate = _PyThreadState_Prealloc(boot->interp);
	if (boot->tstate == NULL) {
		PyMem_DEL(boot);
		return PyErr_NoMemory();
	}
	Py_INCREF(func);
	Py_INCREF(args);
	Py_XINCREF(keyw);
	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
	if (ident == -1) {
		PyErr_SetString(ThreadError, "can't start new thread");
		Py_DECREF(func);
		Py_DECREF(args);
		Py_XDECREF(keyw);
		PyThreadState_Clear(boot->tstate);
		PyMem_DEL(boot);
		return NULL;
	}
	return PyLong_FromLong(ident);
}
예제 #5
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;
}
예제 #6
0
bool PyThread::start() {
	PyScopedLock l(lock);
	if(running) return true;
	stopSignal = false;
	bool expectedRunning = false;
	if(running.compare_exchange_strong(expectedRunning, true)) {
		ident = PyThread_start_new_thread(PyThread_thread, this);
		if(ident == -1) {
			running = false;
			return false;
		}
	}
	else assert(false);
	return true;
}
예제 #7
0
static PyObject*
faulthandler_dump_tracebacks_later(PyObject *self,
                                   PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
    double timeout;
    PY_TIMEOUT_T timeout_us;
    int repeat = 0;
    PyObject *file = NULL;
    int fd;
    int exit = 0;
    PyThreadState *tstate;
    char *header;
    size_t header_len;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "d|iOi:dump_tracebacks_later", kwlist,
        &timeout, &repeat, &file, &exit))
        return NULL;
    if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
        PyErr_SetString(PyExc_OverflowError,  "timeout value is too large");
        return NULL;
    }
    timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
    if (timeout_us <= 0) {
        PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
        return NULL;
    }

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    file = faulthandler_get_fileno(file, &fd);
    if (file == NULL)
        return NULL;

    /* format the timeout */
    header = format_timeout(timeout);
    if (header == NULL)
        return PyErr_NoMemory();
    header_len = strlen(header);

    /* Cancel previous thread, if running */
    cancel_dump_tracebacks_later();

    Py_XDECREF(thread.file);
    Py_INCREF(file);
    thread.file = file;
    thread.fd = fd;
    thread.timeout_us = timeout_us;
    thread.repeat = repeat;
    thread.interp = tstate->interp;
    thread.exit = exit;
    thread.header = header;
    thread.header_len = header_len;

    /* Arm these locks to serve as events when released */
    PyThread_acquire_lock(thread.running, 1);

    if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
        PyThread_release_lock(thread.running);
        Py_CLEAR(thread.file);
        free(header);
        thread.header = NULL;
        PyErr_SetString(PyExc_RuntimeError,
                        "unable to start watchdog thread");
        return NULL;
    }

    Py_RETURN_NONE;
}