Beispiel #1
0
static int green_updatecurrent(void)
{
	if (ts_current == 0)
	{
		/* first time we see this tstate */
		ts_current = green_create_main();
	}
	return 0;
}
Beispiel #2
0
greenlet *greenlet_create(gr_callback cb)
{	
	greenlet *gr = (greenlet *)malloc(sizeof(greenlet));
	memset(gr, 0, sizeof(greenlet));

	if (!ts_current)
		ts_current = green_create_main();

	gr->parent = ts_current;
	gr->callback = cb;
	return gr;
}
Beispiel #3
0
static int green_updatecurrent(void)
{
	PyObject *exc, *val, *tb;
	PyThreadState* tstate;
	PyGreenlet* current;
	PyGreenlet* previous;
	PyObject* deleteme;

	/* save current exception */
	PyErr_Fetch(&exc, &val, &tb);

	/* get ts_current from the active tstate */
	tstate = PyThreadState_GET();
	if (tstate->dict && (current =
	    (PyGreenlet*) PyDict_GetItem(tstate->dict, ts_curkey))) {
		/* found -- remove it, to avoid keeping a ref */
		Py_INCREF(current);
		PyDict_DelItem(tstate->dict, ts_curkey);
	}
	else {
		/* first time we see this tstate */
		current = green_create_main();
		if (current == NULL) {
			Py_XDECREF(exc);
			Py_XDECREF(val);
			Py_XDECREF(tb);
			return -1;
		}
	}

green_updatecurrent_retry:
	/* update ts_current as soon as possible, in case of nested switches */
	Py_INCREF(current);
	previous = ts_current;
	ts_current = current;

	/* save ts_current as the current greenlet of its own thread */
	if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObject*) previous)) {
		Py_DECREF(previous);
		Py_DECREF(current);
		Py_XDECREF(exc);
		Py_XDECREF(val);
		Py_XDECREF(tb);
		return -1;
	}
	Py_DECREF(previous);

	/* green_dealloc() cannot delete greenlets from other threads, so
	   it stores them in the thread dict; delete them now. */
	deleteme = PyDict_GetItem(tstate->dict, ts_delkey);
	if (deleteme != NULL) {
		PyList_SetSlice(deleteme, 0, INT_MAX, NULL);
	}

	if (ts_current != current) {
		/* some Python code executed above and there was a thread switch,
		 * so ts_current points to some other thread again. We need to
		 * delete ts_curkey (it's likely there) and retry. */
		PyDict_DelItem(tstate->dict, ts_curkey);
		goto green_updatecurrent_retry;
	}

	/* release an extra reference */
	Py_DECREF(current);

	/* restore current exception */
	PyErr_Restore(exc, val, tb);

	return 0;
}
Beispiel #4
0
PyMODINIT_FUNC
initgreenlet(void)
#endif
{
	PyObject* m = NULL;
	char** p = NULL;
	PyObject *c_api_object;
	static void *_PyGreenlet_API[PyGreenlet_API_pointers];

	GREENLET_NOINLINE_INIT();

#if PY_MAJOR_VERSION >= 3
	m = PyModule_Create(&greenlet_module_def);
#else
	m = Py_InitModule("greenlet", GreenMethods);
#endif
	if (m == NULL)
	{
		INITERROR;
	}

	if (PyModule_AddStringConstant(m, "__version__", GREENLET_VERSION) < 0)
	{
		INITERROR;
	}

#if PY_MAJOR_VERSION >= 3
	ts_curkey = PyUnicode_InternFromString("__greenlet_ts_curkey");
	ts_delkey = PyUnicode_InternFromString("__greenlet_ts_delkey");
#else
	ts_curkey = PyString_InternFromString("__greenlet_ts_curkey");
	ts_delkey = PyString_InternFromString("__greenlet_ts_delkey");
#endif
	if (ts_curkey == NULL || ts_delkey == NULL)
	{
		INITERROR;
	}
	if (PyType_Ready(&PyGreenlet_Type) < 0)
	{
		INITERROR;
	}
	PyExc_GreenletError = PyErr_NewException("greenlet.error", NULL, NULL);
	if (PyExc_GreenletError == NULL)
	{
		INITERROR;
	}
#if PY_MAJOR_VERSION >= 3 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5)
	PyExc_GreenletExit = PyErr_NewException("greenlet.GreenletExit",
						PyExc_BaseException, NULL);
#else
	PyExc_GreenletExit = PyErr_NewException("greenlet.GreenletExit",
						NULL, NULL);
#endif
	if (PyExc_GreenletExit == NULL)
	{
		INITERROR;
	}

	ts_current = green_create_main();
	if (ts_current == NULL)
	{
		INITERROR;
	}

	Py_INCREF(&PyGreenlet_Type);
	PyModule_AddObject(m, "greenlet", (PyObject*) &PyGreenlet_Type);
	Py_INCREF(PyExc_GreenletError);
	PyModule_AddObject(m, "error", PyExc_GreenletError);
	Py_INCREF(PyExc_GreenletExit);
	PyModule_AddObject(m, "GreenletExit", PyExc_GreenletExit);
#ifdef GREENLET_USE_GC
	PyModule_AddObject(m, "GREENLET_USE_GC", PyBool_FromLong(1));
#else
	PyModule_AddObject(m, "GREENLET_USE_GC", PyBool_FromLong(0));
#endif

        /* also publish module-level data as attributes of the greentype. */
	for (p=copy_on_greentype; *p; p++) {
		PyObject* o = PyObject_GetAttrString(m, *p);
		if (!o) continue;
		PyDict_SetItemString(PyGreenlet_Type.tp_dict, *p, o);
		Py_DECREF(o);
	}

	/*
	 * Expose C API
	 */

	/* types */
	_PyGreenlet_API[PyGreenlet_Type_NUM] = (void *) &PyGreenlet_Type;

	/* exceptions */
	_PyGreenlet_API[PyExc_GreenletError_NUM] = (void *) PyExc_GreenletError;
	_PyGreenlet_API[PyExc_GreenletExit_NUM] = (void *) PyExc_GreenletExit;

	/* methods */
	_PyGreenlet_API[PyGreenlet_New_NUM] = (void *) PyGreenlet_New;
	_PyGreenlet_API[PyGreenlet_GetCurrent_NUM] =
		(void *) PyGreenlet_GetCurrent;
	_PyGreenlet_API[PyGreenlet_Throw_NUM] = (void *) PyGreenlet_Throw;
	_PyGreenlet_API[PyGreenlet_Switch_NUM] = (void *) PyGreenlet_Switch;
	_PyGreenlet_API[PyGreenlet_SetParent_NUM] =
		(void *) PyGreenlet_SetParent;

#ifdef GREENLET_USE_PYCAPSULE
	c_api_object = PyCapsule_New((void *) _PyGreenlet_API, "greenlet._C_API", NULL);
#else
	c_api_object = PyCObject_FromVoidPtr((void *) _PyGreenlet_API, NULL);
#endif
	if (c_api_object != NULL)
	{
		PyModule_AddObject(m, "_C_API", c_api_object);
	}

#if PY_MAJOR_VERSION >= 3
	return m;
#endif
}
Beispiel #5
0
void greenlets_init()
{
	//GREENLET_NOINLINE_INIT();

	ts_current = green_create_main();
}