greenlet.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766
  1. /* vim:set noet ts=8 sw=8 : */
  2. #define GREENLET_MODULE
  3. #include "greenlet.h"
  4. #include "structmember.h"
  5. /***********************************************************
  6. A PyGreenlet is a range of C stack addresses that must be
  7. saved and restored in such a way that the full range of the
  8. stack contains valid data when we switch to it.
  9. Stack layout for a greenlet:
  10. | ^^^ |
  11. | older data |
  12. | |
  13. stack_stop . |_______________|
  14. . | |
  15. . | greenlet data |
  16. . | in stack |
  17. . * |_______________| . . _____________ stack_copy + stack_saved
  18. . | | | |
  19. . | data | |greenlet data|
  20. . | unrelated | | saved |
  21. . | to | | in heap |
  22. stack_start . | this | . . |_____________| stack_copy
  23. | greenlet |
  24. | |
  25. | newer data |
  26. | vvv |
  27. Note that a greenlet's stack data is typically partly at its correct
  28. place in the stack, and partly saved away in the heap, but always in
  29. the above configuration: two blocks, the more recent one in the heap
  30. and the older one still in the stack (either block may be empty).
  31. Greenlets are chained: each points to the previous greenlet, which is
  32. the one that owns the data currently in the C stack above my
  33. stack_stop. The currently running greenlet is the first element of
  34. this chain. The main (initial) greenlet is the last one. Greenlets
  35. whose stack is entirely in the heap can be skipped from the chain.
  36. The chain is not related to execution order, but only to the order
  37. in which bits of C stack happen to belong to greenlets at a particular
  38. point in time.
  39. The main greenlet doesn't have a stack_stop: it is responsible for the
  40. complete rest of the C stack, and we don't know where it begins. We
  41. use (char*) -1, the largest possible address.
  42. States:
  43. stack_stop == NULL && stack_start == NULL: did not start yet
  44. stack_stop != NULL && stack_start == NULL: already finished
  45. stack_stop != NULL && stack_start != NULL: active
  46. The running greenlet's stack_start is undefined but not NULL.
  47. ***********************************************************/
  48. /*** global state ***/
  49. /* In the presence of multithreading, this is a bit tricky:
  50. - ts_current always store a reference to a greenlet, but it is
  51. not really the current greenlet after a thread switch occurred.
  52. - each *running* greenlet uses its run_info field to know which
  53. thread it is attached to. A greenlet can only run in the thread
  54. where it was created. This run_info is a ref to tstate->dict.
  55. - the thread state dict is used to save and restore ts_current,
  56. using the dictionary key 'ts_curkey'.
  57. */
  58. /* Python <= 2.5 support */
  59. #if PY_MAJOR_VERSION < 3
  60. #ifndef Py_REFCNT
  61. # define Py_REFCNT(ob) (((PyObject *) (ob))->ob_refcnt)
  62. #endif
  63. #ifndef Py_TYPE
  64. # define Py_TYPE(ob) (((PyObject *) (ob))->ob_type)
  65. #endif
  66. #ifndef PyVarObject_HEAD_INIT
  67. # define PyVarObject_HEAD_INIT(type, size) \
  68. PyObject_HEAD_INIT(type) size,
  69. #endif
  70. #endif
  71. #if PY_VERSION_HEX < 0x02060000
  72. #define PyLong_FromSsize_t PyInt_FromLong
  73. #endif
  74. #if PY_VERSION_HEX < 0x02050000
  75. typedef int Py_ssize_t;
  76. #endif
  77. extern PyTypeObject PyGreenlet_Type;
  78. /* Defines that customize greenlet module behaviour */
  79. #ifndef GREENLET_USE_GC
  80. #define GREENLET_USE_GC 1
  81. #endif
  82. #ifndef GREENLET_USE_TRACING
  83. #define GREENLET_USE_TRACING 1
  84. #endif
  85. /* Weak reference to the switching-to greenlet during the slp switch */
  86. static PyGreenlet* volatile ts_target = NULL;
  87. /* Strong reference to the switching from greenlet after the switch */
  88. static PyGreenlet* volatile ts_origin = NULL;
  89. /* Strong reference to the current greenlet in this thread state */
  90. static PyGreenlet* volatile ts_current = NULL;
  91. /* NULL if error, otherwise args tuple to pass around during slp switch */
  92. static PyObject* volatile ts_passaround_args = NULL;
  93. static PyObject* volatile ts_passaround_kwargs = NULL;
  94. /***********************************************************/
  95. /* Thread-aware routines, switching global variables when needed */
  96. #define STATE_OK (ts_current->run_info == PyThreadState_GET()->dict \
  97. || !green_updatecurrent())
  98. static PyObject* ts_curkey;
  99. static PyObject* ts_delkey;
  100. #if GREENLET_USE_TRACING
  101. static PyObject* ts_tracekey;
  102. static PyObject* ts_event_switch;
  103. static PyObject* ts_event_throw;
  104. #endif
  105. static PyObject* PyExc_GreenletError;
  106. static PyObject* PyExc_GreenletExit;
  107. static PyObject* ts_empty_tuple;
  108. static PyObject* ts_empty_dict;
  109. #if GREENLET_USE_GC
  110. #define GREENLET_GC_FLAGS Py_TPFLAGS_HAVE_GC
  111. #define GREENLET_tp_alloc PyType_GenericAlloc
  112. #define GREENLET_tp_free PyObject_GC_Del
  113. #define GREENLET_tp_traverse green_traverse
  114. #define GREENLET_tp_clear green_clear
  115. #define GREENLET_tp_is_gc green_is_gc
  116. #else /* GREENLET_USE_GC */
  117. #define GREENLET_GC_FLAGS 0
  118. #define GREENLET_tp_alloc 0
  119. #define GREENLET_tp_free 0
  120. #define GREENLET_tp_traverse 0
  121. #define GREENLET_tp_clear 0
  122. #define GREENLET_tp_is_gc 0
  123. #endif /* !GREENLET_USE_GC */
  124. static void green_clear_exc(PyGreenlet* g)
  125. {
  126. #ifdef GREENLET_USE_EXC_INFO
  127. g->exc_info = NULL;
  128. g->exc_state.exc_type = NULL;
  129. g->exc_state.exc_value = NULL;
  130. g->exc_state.exc_traceback = NULL;
  131. g->exc_state.previous_item = NULL;
  132. #else
  133. g->exc_type = NULL;
  134. g->exc_value = NULL;
  135. g->exc_traceback = NULL;
  136. #endif
  137. }
  138. static PyGreenlet* green_create_main(void)
  139. {
  140. PyGreenlet* gmain;
  141. PyObject* dict = PyThreadState_GetDict();
  142. if (dict == NULL) {
  143. if (!PyErr_Occurred())
  144. PyErr_NoMemory();
  145. return NULL;
  146. }
  147. /* create the main greenlet for this thread */
  148. gmain = (PyGreenlet*) PyType_GenericAlloc(&PyGreenlet_Type, 0);
  149. if (gmain == NULL)
  150. return NULL;
  151. gmain->stack_start = (char*) 1;
  152. gmain->stack_stop = (char*) -1;
  153. gmain->run_info = dict;
  154. Py_INCREF(dict);
  155. return gmain;
  156. }
  157. static int green_updatecurrent(void)
  158. {
  159. PyObject *exc, *val, *tb;
  160. PyThreadState* tstate;
  161. PyGreenlet* current;
  162. PyGreenlet* previous;
  163. PyObject* deleteme;
  164. green_updatecurrent_restart:
  165. /* save current exception */
  166. PyErr_Fetch(&exc, &val, &tb);
  167. /* get ts_current from the active tstate */
  168. tstate = PyThreadState_GET();
  169. if (tstate->dict && (current =
  170. (PyGreenlet*) PyDict_GetItem(tstate->dict, ts_curkey))) {
  171. /* found -- remove it, to avoid keeping a ref */
  172. Py_INCREF(current);
  173. PyDict_DelItem(tstate->dict, ts_curkey);
  174. }
  175. else {
  176. /* first time we see this tstate */
  177. current = green_create_main();
  178. if (current == NULL) {
  179. Py_XDECREF(exc);
  180. Py_XDECREF(val);
  181. Py_XDECREF(tb);
  182. return -1;
  183. }
  184. }
  185. assert(current->run_info == tstate->dict);
  186. green_updatecurrent_retry:
  187. /* update ts_current as soon as possible, in case of nested switches */
  188. Py_INCREF(current);
  189. previous = ts_current;
  190. ts_current = current;
  191. /* save ts_current as the current greenlet of its own thread */
  192. if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObject*) previous)) {
  193. Py_DECREF(previous);
  194. Py_DECREF(current);
  195. Py_XDECREF(exc);
  196. Py_XDECREF(val);
  197. Py_XDECREF(tb);
  198. return -1;
  199. }
  200. Py_DECREF(previous);
  201. /* green_dealloc() cannot delete greenlets from other threads, so
  202. it stores them in the thread dict; delete them now. */
  203. deleteme = PyDict_GetItem(tstate->dict, ts_delkey);
  204. if (deleteme != NULL) {
  205. PyList_SetSlice(deleteme, 0, INT_MAX, NULL);
  206. }
  207. if (ts_current != current) {
  208. /* some Python code executed above and there was a thread switch,
  209. * so ts_current points to some other thread again. We need to
  210. * delete ts_curkey (it's likely there) and retry. */
  211. PyDict_DelItem(tstate->dict, ts_curkey);
  212. goto green_updatecurrent_retry;
  213. }
  214. /* release an extra reference */
  215. Py_DECREF(current);
  216. /* restore current exception */
  217. PyErr_Restore(exc, val, tb);
  218. /* thread switch could happen during PyErr_Restore, in that
  219. case there's nothing to do except restart from scratch. */
  220. if (ts_current->run_info != tstate->dict)
  221. goto green_updatecurrent_restart;
  222. return 0;
  223. }
  224. static PyObject* green_statedict(PyGreenlet* g)
  225. {
  226. while (!PyGreenlet_STARTED(g)) {
  227. g = g->parent;
  228. if (g == NULL) {
  229. /* garbage collected greenlet in chain */
  230. return NULL;
  231. }
  232. }
  233. return g->run_info;
  234. }
  235. /***********************************************************/
  236. /* Some functions must not be inlined:
  237. * slp_restore_state, when inlined into slp_switch might cause
  238. it to restore stack over its own local variables
  239. * slp_save_state, when inlined would add its own local
  240. variables to the saved stack, wasting space
  241. * slp_switch, cannot be inlined for obvious reasons
  242. * g_initialstub, when inlined would receive a pointer into its
  243. own stack frame, leading to incomplete stack save/restore
  244. */
  245. #if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
  246. #define GREENLET_NOINLINE_SUPPORTED
  247. #define GREENLET_NOINLINE(name) __attribute__((noinline)) name
  248. #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
  249. #define GREENLET_NOINLINE_SUPPORTED
  250. #define GREENLET_NOINLINE(name) __declspec(noinline) name
  251. #endif
  252. #ifdef GREENLET_NOINLINE_SUPPORTED
  253. /* add forward declarations */
  254. static void GREENLET_NOINLINE(slp_restore_state)(void);
  255. static int GREENLET_NOINLINE(slp_save_state)(char*);
  256. #if !(defined(MS_WIN64) && defined(_M_X64))
  257. static int GREENLET_NOINLINE(slp_switch)(void);
  258. #endif
  259. static int GREENLET_NOINLINE(g_initialstub)(void*);
  260. #define GREENLET_NOINLINE_INIT() do {} while(0)
  261. #else
  262. /* force compiler to call functions via pointers */
  263. static void (*slp_restore_state)(void);
  264. static int (*slp_save_state)(char*);
  265. static int (*slp_switch)(void);
  266. static int (*g_initialstub)(void*);
  267. #define GREENLET_NOINLINE(name) cannot_inline_ ## name
  268. #define GREENLET_NOINLINE_INIT() do { \
  269. slp_restore_state = GREENLET_NOINLINE(slp_restore_state); \
  270. slp_save_state = GREENLET_NOINLINE(slp_save_state); \
  271. slp_switch = GREENLET_NOINLINE(slp_switch); \
  272. g_initialstub = GREENLET_NOINLINE(g_initialstub); \
  273. } while(0)
  274. #endif
  275. /*
  276. * the following macros are spliced into the OS/compiler
  277. * specific code, in order to simplify maintenance.
  278. */
  279. #define SLP_SAVE_STATE(stackref, stsizediff) \
  280. stackref += STACK_MAGIC; \
  281. if (slp_save_state((char*)stackref)) return -1; \
  282. if (!PyGreenlet_ACTIVE(ts_target)) return 1; \
  283. stsizediff = ts_target->stack_start - (char*)stackref
  284. #define SLP_RESTORE_STATE() \
  285. slp_restore_state()
  286. #define SLP_EVAL
  287. #define slp_switch GREENLET_NOINLINE(slp_switch)
  288. #include "slp_platformselect.h"
  289. #undef slp_switch
  290. #ifndef STACK_MAGIC
  291. #error "greenlet needs to be ported to this platform, or teached how to detect your compiler properly."
  292. #endif /* !STACK_MAGIC */
  293. #ifdef EXTERNAL_ASM
  294. /* CCP addition: Make these functions, to be called from assembler.
  295. * The token include file for the given platform should enable the
  296. * EXTERNAL_ASM define so that this is included.
  297. */
  298. intptr_t slp_save_state_asm(intptr_t *ref) {
  299. intptr_t diff;
  300. SLP_SAVE_STATE(ref, diff);
  301. return diff;
  302. }
  303. void slp_restore_state_asm(void) {
  304. SLP_RESTORE_STATE();
  305. }
  306. extern int slp_switch(void);
  307. #endif
  308. /***********************************************************/
  309. static int g_save(PyGreenlet* g, char* stop)
  310. {
  311. /* Save more of g's stack into the heap -- at least up to 'stop'
  312. g->stack_stop |________|
  313. | |
  314. | __ stop . . . . .
  315. | | ==> . .
  316. |________| _______
  317. | | | |
  318. | | | |
  319. g->stack_start | | |_______| g->stack_copy
  320. */
  321. intptr_t sz1 = g->stack_saved;
  322. intptr_t sz2 = stop - g->stack_start;
  323. assert(g->stack_start != NULL);
  324. if (sz2 > sz1) {
  325. char* c = (char*)PyMem_Realloc(g->stack_copy, sz2);
  326. if (!c) {
  327. PyErr_NoMemory();
  328. return -1;
  329. }
  330. memcpy(c+sz1, g->stack_start+sz1, sz2-sz1);
  331. g->stack_copy = c;
  332. g->stack_saved = sz2;
  333. }
  334. return 0;
  335. }
  336. static void GREENLET_NOINLINE(slp_restore_state)(void)
  337. {
  338. PyGreenlet* g = ts_target;
  339. PyGreenlet* owner = ts_current;
  340. #ifdef SLP_BEFORE_RESTORE_STATE
  341. SLP_BEFORE_RESTORE_STATE();
  342. #endif
  343. /* Restore the heap copy back into the C stack */
  344. if (g->stack_saved != 0) {
  345. memcpy(g->stack_start, g->stack_copy, g->stack_saved);
  346. PyMem_Free(g->stack_copy);
  347. g->stack_copy = NULL;
  348. g->stack_saved = 0;
  349. }
  350. if (owner->stack_start == NULL)
  351. owner = owner->stack_prev; /* greenlet is dying, skip it */
  352. while (owner && owner->stack_stop <= g->stack_stop)
  353. owner = owner->stack_prev; /* find greenlet with more stack */
  354. g->stack_prev = owner;
  355. }
  356. static int GREENLET_NOINLINE(slp_save_state)(char* stackref)
  357. {
  358. /* must free all the C stack up to target_stop */
  359. char* target_stop = ts_target->stack_stop;
  360. PyGreenlet* owner = ts_current;
  361. assert(owner->stack_saved == 0);
  362. if (owner->stack_start == NULL)
  363. owner = owner->stack_prev; /* not saved if dying */
  364. else
  365. owner->stack_start = stackref;
  366. #ifdef SLP_BEFORE_SAVE_STATE
  367. SLP_BEFORE_SAVE_STATE();
  368. #endif
  369. while (owner->stack_stop < target_stop) {
  370. /* ts_current is entierely within the area to free */
  371. if (g_save(owner, owner->stack_stop))
  372. return -1; /* XXX */
  373. owner = owner->stack_prev;
  374. }
  375. if (owner != ts_target) {
  376. if (g_save(owner, target_stop))
  377. return -1; /* XXX */
  378. }
  379. return 0;
  380. }
  381. static int g_switchstack(void)
  382. {
  383. /* Perform a stack switch according to some global variables
  384. that must be set before:
  385. - ts_current: current greenlet (holds a reference)
  386. - ts_target: greenlet to switch to (weak reference)
  387. - ts_passaround_args: NULL if PyErr_Occurred(),
  388. else a tuple of args sent to ts_target (holds a reference)
  389. - ts_passaround_kwargs: switch kwargs (holds a reference)
  390. On return results are passed via global variables as well:
  391. - ts_origin: originating greenlet (holds a reference)
  392. - ts_current: current greenlet (holds a reference)
  393. - ts_passaround_args: NULL if PyErr_Occurred(),
  394. else a tuple of args sent to ts_current (holds a reference)
  395. - ts_passaround_kwargs: switch kwargs (holds a reference)
  396. It is very important that stack switch is 'atomic', i.e. no
  397. calls into other Python code allowed (except very few that
  398. are safe), because global variables are very fragile.
  399. */
  400. int err;
  401. { /* save state */
  402. PyGreenlet* current = ts_current;
  403. PyThreadState* tstate = PyThreadState_GET();
  404. current->recursion_depth = tstate->recursion_depth;
  405. current->top_frame = tstate->frame;
  406. #ifdef GREENLET_USE_EXC_INFO
  407. current->exc_info = tstate->exc_info;
  408. current->exc_state = tstate->exc_state;
  409. #else
  410. current->exc_type = tstate->exc_type;
  411. current->exc_value = tstate->exc_value;
  412. current->exc_traceback = tstate->exc_traceback;
  413. #endif
  414. }
  415. err = slp_switch();
  416. if (err < 0) { /* error */
  417. PyGreenlet* current = ts_current;
  418. current->top_frame = NULL;
  419. #ifdef GREENLET_USE_EXC_INFO
  420. green_clear_exc(current);
  421. #else
  422. current->exc_type = NULL;
  423. current->exc_value = NULL;
  424. current->exc_traceback = NULL;
  425. #endif
  426. assert(ts_origin == NULL);
  427. ts_target = NULL;
  428. }
  429. else {
  430. PyGreenlet* target = ts_target;
  431. PyGreenlet* origin = ts_current;
  432. PyThreadState* tstate = PyThreadState_GET();
  433. tstate->recursion_depth = target->recursion_depth;
  434. tstate->frame = target->top_frame;
  435. target->top_frame = NULL;
  436. #ifdef GREENLET_USE_EXC_INFO
  437. tstate->exc_state = target->exc_state;
  438. tstate->exc_info = target->exc_info ? target->exc_info : &tstate->exc_state;
  439. #else
  440. tstate->exc_type = target->exc_type;
  441. tstate->exc_value = target->exc_value;
  442. tstate->exc_traceback = target->exc_traceback;
  443. #endif
  444. green_clear_exc(target);
  445. assert(ts_origin == NULL);
  446. Py_INCREF(target);
  447. ts_current = target;
  448. ts_origin = origin;
  449. ts_target = NULL;
  450. }
  451. return err;
  452. }
  453. #if GREENLET_USE_TRACING
  454. static int
  455. g_calltrace(PyObject* tracefunc, PyObject* event, PyGreenlet* origin, PyGreenlet* target)
  456. {
  457. PyObject *retval;
  458. PyObject *exc_type, *exc_val, *exc_tb;
  459. PyThreadState *tstate;
  460. PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
  461. tstate = PyThreadState_GET();
  462. tstate->tracing++;
  463. tstate->use_tracing = 0;
  464. retval = PyObject_CallFunction(tracefunc, "O(OO)", event, origin, target);
  465. tstate->tracing--;
  466. tstate->use_tracing = (tstate->tracing <= 0 &&
  467. ((tstate->c_tracefunc != NULL) ||
  468. (tstate->c_profilefunc != NULL)));
  469. if (retval == NULL) {
  470. /* In case of exceptions trace function is removed */
  471. if (PyDict_GetItem(tstate->dict, ts_tracekey))
  472. PyDict_DelItem(tstate->dict, ts_tracekey);
  473. Py_XDECREF(exc_type);
  474. Py_XDECREF(exc_val);
  475. Py_XDECREF(exc_tb);
  476. return -1;
  477. } else
  478. Py_DECREF(retval);
  479. PyErr_Restore(exc_type, exc_val, exc_tb);
  480. return 0;
  481. }
  482. #endif
  483. static PyObject *
  484. g_switch(PyGreenlet* target, PyObject* args, PyObject* kwargs)
  485. {
  486. /* _consumes_ a reference to the args tuple and kwargs dict,
  487. and return a new tuple reference */
  488. int err = 0;
  489. PyObject* run_info;
  490. /* check ts_current */
  491. if (!STATE_OK) {
  492. Py_XDECREF(args);
  493. Py_XDECREF(kwargs);
  494. return NULL;
  495. }
  496. run_info = green_statedict(target);
  497. if (run_info == NULL || run_info != ts_current->run_info) {
  498. Py_XDECREF(args);
  499. Py_XDECREF(kwargs);
  500. PyErr_SetString(PyExc_GreenletError, run_info
  501. ? "cannot switch to a different thread"
  502. : "cannot switch to a garbage collected greenlet");
  503. return NULL;
  504. }
  505. ts_passaround_args = args;
  506. ts_passaround_kwargs = kwargs;
  507. /* find the real target by ignoring dead greenlets,
  508. and if necessary starting a greenlet. */
  509. while (target) {
  510. if (PyGreenlet_ACTIVE(target)) {
  511. ts_target = target;
  512. err = g_switchstack();
  513. break;
  514. }
  515. if (!PyGreenlet_STARTED(target)) {
  516. void* dummymarker;
  517. ts_target = target;
  518. err = g_initialstub(&dummymarker);
  519. if (err == 1) {
  520. continue; /* retry the switch */
  521. }
  522. break;
  523. }
  524. target = target->parent;
  525. }
  526. /* For a very short time, immediately after the 'atomic'
  527. g_switchstack() call, global variables are in a known state.
  528. We need to save everything we need, before it is destroyed
  529. by calls into arbitrary Python code. */
  530. args = ts_passaround_args;
  531. ts_passaround_args = NULL;
  532. kwargs = ts_passaround_kwargs;
  533. ts_passaround_kwargs = NULL;
  534. if (err < 0) {
  535. /* Turn switch errors into switch throws */
  536. assert(ts_origin == NULL);
  537. Py_CLEAR(kwargs);
  538. Py_CLEAR(args);
  539. } else {
  540. PyGreenlet *origin;
  541. #if GREENLET_USE_TRACING
  542. PyGreenlet *current;
  543. PyObject *tracefunc;
  544. #endif
  545. origin = ts_origin;
  546. ts_origin = NULL;
  547. #if GREENLET_USE_TRACING
  548. current = ts_current;
  549. if ((tracefunc = PyDict_GetItem(current->run_info, ts_tracekey)) != NULL) {
  550. Py_INCREF(tracefunc);
  551. if (g_calltrace(tracefunc, args ? ts_event_switch : ts_event_throw, origin, current) < 0) {
  552. /* Turn trace errors into switch throws */
  553. Py_CLEAR(kwargs);
  554. Py_CLEAR(args);
  555. }
  556. Py_DECREF(tracefunc);
  557. }
  558. #endif
  559. Py_DECREF(origin);
  560. }
  561. /* We need to figure out what values to pass to the target greenlet
  562. based on the arguments that have been passed to greenlet.switch(). If
  563. switch() was just passed an arg tuple, then we'll just return that.
  564. If only keyword arguments were passed, then we'll pass the keyword
  565. argument dict. Otherwise, we'll create a tuple of (args, kwargs) and
  566. return both. */
  567. if (kwargs == NULL)
  568. {
  569. return args;
  570. }
  571. else if (PyDict_Size(kwargs) == 0)
  572. {
  573. Py_DECREF(kwargs);
  574. return args;
  575. }
  576. else if (PySequence_Length(args) == 0)
  577. {
  578. Py_DECREF(args);
  579. return kwargs;
  580. }
  581. else
  582. {
  583. PyObject *tuple = PyTuple_New(2);
  584. if (tuple == NULL) {
  585. Py_DECREF(args);
  586. Py_DECREF(kwargs);
  587. return NULL;
  588. }
  589. PyTuple_SET_ITEM(tuple, 0, args);
  590. PyTuple_SET_ITEM(tuple, 1, kwargs);
  591. return tuple;
  592. }
  593. }
  594. static PyObject *
  595. g_handle_exit(PyObject *result)
  596. {
  597. if (result == NULL && PyErr_ExceptionMatches(PyExc_GreenletExit))
  598. {
  599. /* catch and ignore GreenletExit */
  600. PyObject *exc, *val, *tb;
  601. PyErr_Fetch(&exc, &val, &tb);
  602. if (val == NULL)
  603. {
  604. Py_INCREF(Py_None);
  605. val = Py_None;
  606. }
  607. result = val;
  608. Py_DECREF(exc);
  609. Py_XDECREF(tb);
  610. }
  611. if (result != NULL)
  612. {
  613. /* package the result into a 1-tuple */
  614. PyObject *r = result;
  615. result = PyTuple_New(1);
  616. if (result)
  617. {
  618. PyTuple_SET_ITEM(result, 0, r);
  619. }
  620. else
  621. {
  622. Py_DECREF(r);
  623. }
  624. }
  625. return result;
  626. }
  627. static int GREENLET_NOINLINE(g_initialstub)(void* mark)
  628. {
  629. int err;
  630. PyObject *o, *run;
  631. PyObject *exc, *val, *tb;
  632. PyObject *run_info;
  633. PyGreenlet* self = ts_target;
  634. PyObject* args = ts_passaround_args;
  635. PyObject* kwargs = ts_passaround_kwargs;
  636. /* save exception in case getattr clears it */
  637. PyErr_Fetch(&exc, &val, &tb);
  638. /* self.run is the object to call in the new greenlet */
  639. run = PyObject_GetAttrString((PyObject*) self, "run");
  640. if (run == NULL) {
  641. Py_XDECREF(exc);
  642. Py_XDECREF(val);
  643. Py_XDECREF(tb);
  644. return -1;
  645. }
  646. /* restore saved exception */
  647. PyErr_Restore(exc, val, tb);
  648. /* recheck the state in case getattr caused thread switches */
  649. if (!STATE_OK) {
  650. Py_DECREF(run);
  651. return -1;
  652. }
  653. /* recheck run_info in case greenlet reparented anywhere above */
  654. run_info = green_statedict(self);
  655. if (run_info == NULL || run_info != ts_current->run_info) {
  656. Py_DECREF(run);
  657. PyErr_SetString(PyExc_GreenletError, run_info
  658. ? "cannot switch to a different thread"
  659. : "cannot switch to a garbage collected greenlet");
  660. return -1;
  661. }
  662. /* by the time we got here another start could happen elsewhere,
  663. * that means it should now be a regular switch
  664. */
  665. if (PyGreenlet_STARTED(self)) {
  666. Py_DECREF(run);
  667. ts_passaround_args = args;
  668. ts_passaround_kwargs = kwargs;
  669. return 1;
  670. }
  671. /* start the greenlet */
  672. self->stack_start = NULL;
  673. self->stack_stop = (char*) mark;
  674. if (ts_current->stack_start == NULL) {
  675. /* ts_current is dying */
  676. self->stack_prev = ts_current->stack_prev;
  677. }
  678. else {
  679. self->stack_prev = ts_current;
  680. }
  681. self->top_frame = NULL;
  682. green_clear_exc(self);
  683. self->recursion_depth = PyThreadState_GET()->recursion_depth;
  684. /* restore arguments in case they are clobbered */
  685. ts_target = self;
  686. ts_passaround_args = args;
  687. ts_passaround_kwargs = kwargs;
  688. /* perform the initial switch */
  689. err = g_switchstack();
  690. /* returns twice!
  691. The 1st time with err=1: we are in the new greenlet
  692. The 2nd time with err=0: back in the caller's greenlet
  693. */
  694. if (err == 1) {
  695. /* in the new greenlet */
  696. PyGreenlet* origin;
  697. #if GREENLET_USE_TRACING
  698. PyObject* tracefunc;
  699. #endif
  700. PyObject* result;
  701. PyGreenlet* parent;
  702. self->stack_start = (char*) 1; /* running */
  703. /* grab origin while we still can */
  704. origin = ts_origin;
  705. ts_origin = NULL;
  706. /* now use run_info to store the statedict */
  707. o = self->run_info;
  708. self->run_info = green_statedict(self->parent);
  709. Py_INCREF(self->run_info);
  710. Py_XDECREF(o);
  711. #if GREENLET_USE_TRACING
  712. if ((tracefunc = PyDict_GetItem(self->run_info, ts_tracekey)) != NULL) {
  713. Py_INCREF(tracefunc);
  714. if (g_calltrace(tracefunc, args ? ts_event_switch : ts_event_throw, origin, self) < 0) {
  715. /* Turn trace errors into switch throws */
  716. Py_CLEAR(kwargs);
  717. Py_CLEAR(args);
  718. }
  719. Py_DECREF(tracefunc);
  720. }
  721. #endif
  722. Py_DECREF(origin);
  723. if (args == NULL) {
  724. /* pending exception */
  725. result = NULL;
  726. } else {
  727. /* call g.run(*args, **kwargs) */
  728. result = PyEval_CallObjectWithKeywords(
  729. run, args, kwargs);
  730. Py_DECREF(args);
  731. Py_XDECREF(kwargs);
  732. }
  733. Py_DECREF(run);
  734. result = g_handle_exit(result);
  735. /* jump back to parent */
  736. self->stack_start = NULL; /* dead */
  737. for (parent = self->parent; parent != NULL; parent = parent->parent) {
  738. result = g_switch(parent, result, NULL);
  739. /* Return here means switch to parent failed,
  740. * in which case we throw *current* exception
  741. * to the next parent in chain.
  742. */
  743. assert(result == NULL);
  744. }
  745. /* We ran out of parents, cannot continue */
  746. PyErr_WriteUnraisable((PyObject *) self);
  747. Py_FatalError("greenlets cannot continue");
  748. }
  749. /* back in the parent */
  750. if (err < 0) {
  751. /* start failed badly, restore greenlet state */
  752. self->stack_start = NULL;
  753. self->stack_stop = NULL;
  754. self->stack_prev = NULL;
  755. }
  756. return err;
  757. }
  758. /***********************************************************/
  759. static PyObject* green_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  760. {
  761. PyObject* o = PyBaseObject_Type.tp_new(type, ts_empty_tuple, ts_empty_dict);
  762. if (o != NULL) {
  763. if (!STATE_OK) {
  764. Py_DECREF(o);
  765. return NULL;
  766. }
  767. Py_INCREF(ts_current);
  768. ((PyGreenlet*) o)->parent = ts_current;
  769. }
  770. return o;
  771. }
  772. static int green_setrun(PyGreenlet* self, PyObject* nrun, void* c);
  773. static int green_setparent(PyGreenlet* self, PyObject* nparent, void* c);
  774. static int green_init(PyGreenlet *self, PyObject *args, PyObject *kwargs)
  775. {
  776. PyObject *run = NULL;
  777. PyObject* nparent = NULL;
  778. static char *kwlist[] = {"run", "parent", 0};
  779. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:green", kwlist,
  780. &run, &nparent))
  781. return -1;
  782. if (run != NULL) {
  783. if (green_setrun(self, run, NULL))
  784. return -1;
  785. }
  786. if (nparent != NULL && nparent != Py_None)
  787. return green_setparent(self, nparent, NULL);
  788. return 0;
  789. }
  790. static int kill_greenlet(PyGreenlet* self)
  791. {
  792. /* Cannot raise an exception to kill the greenlet if
  793. it is not running in the same thread! */
  794. if (self->run_info == PyThreadState_GET()->dict) {
  795. /* The dying greenlet cannot be a parent of ts_current
  796. because the 'parent' field chain would hold a
  797. reference */
  798. PyObject* result;
  799. PyGreenlet* oldparent;
  800. PyGreenlet* tmp;
  801. if (!STATE_OK) {
  802. return -1;
  803. }
  804. oldparent = self->parent;
  805. self->parent = ts_current;
  806. Py_INCREF(self->parent);
  807. /* Send the greenlet a GreenletExit exception. */
  808. PyErr_SetNone(PyExc_GreenletExit);
  809. result = g_switch(self, NULL, NULL);
  810. tmp = self->parent;
  811. self->parent = oldparent;
  812. Py_XDECREF(tmp);
  813. if (result == NULL)
  814. return -1;
  815. Py_DECREF(result);
  816. return 0;
  817. }
  818. else {
  819. /* Not the same thread! Temporarily save the greenlet
  820. into its thread's ts_delkey list. */
  821. PyObject* lst;
  822. lst = PyDict_GetItem(self->run_info, ts_delkey);
  823. if (lst == NULL) {
  824. lst = PyList_New(0);
  825. if (lst == NULL || PyDict_SetItem(self->run_info,
  826. ts_delkey, lst) < 0)
  827. return -1;
  828. }
  829. if (PyList_Append(lst, (PyObject*) self) < 0)
  830. return -1;
  831. if (!STATE_OK) /* to force ts_delkey to be reconsidered */
  832. return -1;
  833. return 0;
  834. }
  835. }
  836. #if GREENLET_USE_GC
  837. static int
  838. green_traverse(PyGreenlet *self, visitproc visit, void *arg)
  839. {
  840. /* We must only visit referenced objects, i.e. only objects
  841. Py_INCREF'ed by this greenlet (directly or indirectly):
  842. - stack_prev is not visited: holds previous stack pointer, but it's not referenced
  843. - frames are not visited: alive greenlets are not garbage collected anyway */
  844. Py_VISIT((PyObject*)self->parent);
  845. Py_VISIT(self->run_info);
  846. #ifdef GREENLET_USE_EXC_INFO
  847. Py_VISIT(self->exc_state.exc_type);
  848. Py_VISIT(self->exc_state.exc_value);
  849. Py_VISIT(self->exc_state.exc_traceback);
  850. #else
  851. Py_VISIT(self->exc_type);
  852. Py_VISIT(self->exc_value);
  853. Py_VISIT(self->exc_traceback);
  854. #endif
  855. Py_VISIT(self->dict);
  856. return 0;
  857. }
  858. static int green_is_gc(PyGreenlet* self)
  859. {
  860. /* Main greenlet can be garbage collected since it can only
  861. become unreachable if the underlying thread exited.
  862. Active greenlet cannot be garbage collected, however. */
  863. if (PyGreenlet_MAIN(self) || !PyGreenlet_ACTIVE(self))
  864. return 1;
  865. return 0;
  866. }
  867. static int green_clear(PyGreenlet* self)
  868. {
  869. /* Greenlet is only cleared if it is about to be collected.
  870. Since active greenlets are not garbage collectable, we can
  871. be sure that, even if they are deallocated during clear,
  872. nothing they reference is in unreachable or finalizers,
  873. so even if it switches we are relatively safe. */
  874. Py_CLEAR(self->parent);
  875. Py_CLEAR(self->run_info);
  876. #ifdef GREENLET_USE_EXC_INFO
  877. Py_CLEAR(self->exc_state.exc_type);
  878. Py_CLEAR(self->exc_state.exc_value);
  879. Py_CLEAR(self->exc_state.exc_traceback);
  880. #else
  881. Py_CLEAR(self->exc_type);
  882. Py_CLEAR(self->exc_value);
  883. Py_CLEAR(self->exc_traceback);
  884. #endif
  885. Py_CLEAR(self->dict);
  886. return 0;
  887. }
  888. #endif
  889. static void green_dealloc(PyGreenlet* self)
  890. {
  891. PyObject *error_type, *error_value, *error_traceback;
  892. #if GREENLET_USE_GC
  893. PyObject_GC_UnTrack(self);
  894. #endif
  895. if (PyGreenlet_ACTIVE(self) && self->run_info != NULL && !PyGreenlet_MAIN(self)) {
  896. /* Hacks hacks hacks copied from instance_dealloc() */
  897. /* Temporarily resurrect the greenlet. */
  898. assert(Py_REFCNT(self) == 0);
  899. Py_REFCNT(self) = 1;
  900. /* Save the current exception, if any. */
  901. PyErr_Fetch(&error_type, &error_value, &error_traceback);
  902. if (kill_greenlet(self) < 0) {
  903. PyErr_WriteUnraisable((PyObject*) self);
  904. /* XXX what else should we do? */
  905. }
  906. /* Check for no resurrection must be done while we keep
  907. * our internal reference, otherwise PyFile_WriteObject
  908. * causes recursion if using Py_INCREF/Py_DECREF
  909. */
  910. if (Py_REFCNT(self) == 1 && PyGreenlet_ACTIVE(self)) {
  911. /* Not resurrected, but still not dead!
  912. XXX what else should we do? we complain. */
  913. PyObject* f = PySys_GetObject("stderr");
  914. Py_INCREF(self); /* leak! */
  915. if (f != NULL) {
  916. PyFile_WriteString("GreenletExit did not kill ",
  917. f);
  918. PyFile_WriteObject((PyObject*) self, f, 0);
  919. PyFile_WriteString("\n", f);
  920. }
  921. }
  922. /* Restore the saved exception. */
  923. PyErr_Restore(error_type, error_value, error_traceback);
  924. /* Undo the temporary resurrection; can't use DECREF here,
  925. * it would cause a recursive call.
  926. */
  927. assert(Py_REFCNT(self) > 0);
  928. if (--Py_REFCNT(self) != 0) {
  929. /* Resurrected! */
  930. Py_ssize_t refcnt = Py_REFCNT(self);
  931. _Py_NewReference((PyObject*) self);
  932. Py_REFCNT(self) = refcnt;
  933. #if GREENLET_USE_GC
  934. PyObject_GC_Track((PyObject *)self);
  935. #endif
  936. _Py_DEC_REFTOTAL;
  937. #ifdef COUNT_ALLOCS
  938. --Py_TYPE(self)->tp_frees;
  939. --Py_TYPE(self)->tp_allocs;
  940. #endif /* COUNT_ALLOCS */
  941. return;
  942. }
  943. }
  944. if (self->weakreflist != NULL)
  945. PyObject_ClearWeakRefs((PyObject *) self);
  946. Py_CLEAR(self->parent);
  947. Py_CLEAR(self->run_info);
  948. #ifdef GREENLET_USE_EXC_INFO
  949. Py_CLEAR(self->exc_state.exc_type);
  950. Py_CLEAR(self->exc_state.exc_value);
  951. Py_CLEAR(self->exc_state.exc_traceback);
  952. #else
  953. Py_CLEAR(self->exc_type);
  954. Py_CLEAR(self->exc_value);
  955. Py_CLEAR(self->exc_traceback);
  956. #endif
  957. Py_CLEAR(self->dict);
  958. Py_TYPE(self)->tp_free((PyObject*) self);
  959. }
  960. static PyObject* single_result(PyObject* results)
  961. {
  962. if (results != NULL && PyTuple_Check(results) &&
  963. PyTuple_GET_SIZE(results) == 1) {
  964. PyObject *result = PyTuple_GET_ITEM(results, 0);
  965. Py_INCREF(result);
  966. Py_DECREF(results);
  967. return result;
  968. }
  969. else
  970. return results;
  971. }
  972. static PyObject *
  973. throw_greenlet(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)
  974. {
  975. /* Note: _consumes_ a reference to typ, val, tb */
  976. PyObject *result = NULL;
  977. PyErr_Restore(typ, val, tb);
  978. if (PyGreenlet_STARTED(self) && !PyGreenlet_ACTIVE(self))
  979. {
  980. /* dead greenlet: turn GreenletExit into a regular return */
  981. result = g_handle_exit(result);
  982. }
  983. return single_result(g_switch(self, result, NULL));
  984. }
  985. PyDoc_STRVAR(green_switch_doc,
  986. "switch(*args, **kwargs)\n"
  987. "\n"
  988. "Switch execution to this greenlet.\n"
  989. "\n"
  990. "If this greenlet has never been run, then this greenlet\n"
  991. "will be switched to using the body of self.run(*args, **kwargs).\n"
  992. "\n"
  993. "If the greenlet is active (has been run, but was switch()'ed\n"
  994. "out before leaving its run function), then this greenlet will\n"
  995. "be resumed and the return value to its switch call will be\n"
  996. "None if no arguments are given, the given argument if one\n"
  997. "argument is given, or the args tuple and keyword args dict if\n"
  998. "multiple arguments are given.\n"
  999. "\n"
  1000. "If the greenlet is dead, or is the current greenlet then this\n"
  1001. "function will simply return the arguments using the same rules as\n"
  1002. "above.\n");
  1003. static PyObject* green_switch(
  1004. PyGreenlet* self,
  1005. PyObject* args,
  1006. PyObject* kwargs)
  1007. {
  1008. Py_INCREF(args);
  1009. Py_XINCREF(kwargs);
  1010. return single_result(g_switch(self, args, kwargs));
  1011. }
  1012. /* Macros required to support Python < 2.6 for green_throw() */
  1013. #ifndef PyExceptionClass_Check
  1014. # define PyExceptionClass_Check PyClass_Check
  1015. #endif
  1016. #ifndef PyExceptionInstance_Check
  1017. # define PyExceptionInstance_Check PyInstance_Check
  1018. #endif
  1019. #ifndef PyExceptionInstance_Class
  1020. # define PyExceptionInstance_Class(x) \
  1021. ((PyObject *) ((PyInstanceObject *)(x))->in_class)
  1022. #endif
  1023. PyDoc_STRVAR(green_throw_doc,
  1024. "Switches execution to the greenlet ``g``, but immediately raises the\n"
  1025. "given exception in ``g``. If no argument is provided, the exception\n"
  1026. "defaults to ``greenlet.GreenletExit``. The normal exception\n"
  1027. "propagation rules apply, as described above. Note that calling this\n"
  1028. "method is almost equivalent to the following::\n"
  1029. "\n"
  1030. " def raiser():\n"
  1031. " raise typ, val, tb\n"
  1032. " g_raiser = greenlet(raiser, parent=g)\n"
  1033. " g_raiser.switch()\n"
  1034. "\n"
  1035. "except that this trick does not work for the\n"
  1036. "``greenlet.GreenletExit`` exception, which would not propagate\n"
  1037. "from ``g_raiser`` to ``g``.\n");
  1038. static PyObject *
  1039. green_throw(PyGreenlet *self, PyObject *args)
  1040. {
  1041. PyObject *typ = PyExc_GreenletExit;
  1042. PyObject *val = NULL;
  1043. PyObject *tb = NULL;
  1044. if (!PyArg_ParseTuple(args, "|OOO:throw", &typ, &val, &tb))
  1045. {
  1046. return NULL;
  1047. }
  1048. /* First, check the traceback argument, replacing None, with NULL */
  1049. if (tb == Py_None)
  1050. {
  1051. tb = NULL;
  1052. }
  1053. else if (tb != NULL && !PyTraceBack_Check(tb))
  1054. {
  1055. PyErr_SetString(
  1056. PyExc_TypeError,
  1057. "throw() third argument must be a traceback object");
  1058. return NULL;
  1059. }
  1060. Py_INCREF(typ);
  1061. Py_XINCREF(val);
  1062. Py_XINCREF(tb);
  1063. if (PyExceptionClass_Check(typ))
  1064. {
  1065. PyErr_NormalizeException(&typ, &val, &tb);
  1066. }
  1067. else if (PyExceptionInstance_Check(typ))
  1068. {
  1069. /* Raising an instance. The value should be a dummy. */
  1070. if (val && val != Py_None)
  1071. {
  1072. PyErr_SetString(
  1073. PyExc_TypeError,
  1074. "instance exception may not have a separate value");
  1075. goto failed_throw;
  1076. }
  1077. else
  1078. {
  1079. /* Normalize to raise <class>, <instance> */
  1080. Py_XDECREF(val);
  1081. val = typ;
  1082. typ = PyExceptionInstance_Class(typ);
  1083. Py_INCREF(typ);
  1084. }
  1085. }
  1086. else
  1087. {
  1088. /* Not something you can raise. throw() fails. */
  1089. PyErr_Format(
  1090. PyExc_TypeError,
  1091. "exceptions must be classes, or instances, not %s",
  1092. Py_TYPE(typ)->tp_name);
  1093. goto failed_throw;
  1094. }
  1095. return throw_greenlet(self, typ, val, tb);
  1096. failed_throw:
  1097. /* Didn't use our arguments, so restore their original refcounts */
  1098. Py_DECREF(typ);
  1099. Py_XDECREF(val);
  1100. Py_XDECREF(tb);
  1101. return NULL;
  1102. }
  1103. static int green_bool(PyGreenlet* self)
  1104. {
  1105. return PyGreenlet_ACTIVE(self);
  1106. }
  1107. static PyObject* green_getdict(PyGreenlet* self, void* c)
  1108. {
  1109. if (self->dict == NULL) {
  1110. self->dict = PyDict_New();
  1111. if (self->dict == NULL)
  1112. return NULL;
  1113. }
  1114. Py_INCREF(self->dict);
  1115. return self->dict;
  1116. }
  1117. static int green_setdict(PyGreenlet* self, PyObject* val, void* c)
  1118. {
  1119. PyObject* tmp;
  1120. if (val == NULL) {
  1121. PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
  1122. return -1;
  1123. }
  1124. if (!PyDict_Check(val)) {
  1125. PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
  1126. return -1;
  1127. }
  1128. tmp = self->dict;
  1129. Py_INCREF(val);
  1130. self->dict = val;
  1131. Py_XDECREF(tmp);
  1132. return 0;
  1133. }
  1134. static PyObject* green_getdead(PyGreenlet* self, void* c)
  1135. {
  1136. if (PyGreenlet_ACTIVE(self) || !PyGreenlet_STARTED(self))
  1137. Py_RETURN_FALSE;
  1138. else
  1139. Py_RETURN_TRUE;
  1140. }
  1141. static PyObject* green_get_stack_saved(PyGreenlet* self, void* c)
  1142. {
  1143. return PyLong_FromSsize_t(self->stack_saved);
  1144. }
  1145. static PyObject* green_getrun(PyGreenlet* self, void* c)
  1146. {
  1147. if (PyGreenlet_STARTED(self) || self->run_info == NULL) {
  1148. PyErr_SetString(PyExc_AttributeError, "run");
  1149. return NULL;
  1150. }
  1151. Py_INCREF(self->run_info);
  1152. return self->run_info;
  1153. }
  1154. static int green_setrun(PyGreenlet* self, PyObject* nrun, void* c)
  1155. {
  1156. PyObject* o;
  1157. if (PyGreenlet_STARTED(self)) {
  1158. PyErr_SetString(PyExc_AttributeError,
  1159. "run cannot be set "
  1160. "after the start of the greenlet");
  1161. return -1;
  1162. }
  1163. o = self->run_info;
  1164. self->run_info = nrun;
  1165. Py_XINCREF(nrun);
  1166. Py_XDECREF(o);
  1167. return 0;
  1168. }
  1169. static PyObject* green_getparent(PyGreenlet* self, void* c)
  1170. {
  1171. PyObject* result = self->parent ? (PyObject*) self->parent : Py_None;
  1172. Py_INCREF(result);
  1173. return result;
  1174. }
  1175. static int green_setparent(PyGreenlet* self, PyObject* nparent, void* c)
  1176. {
  1177. PyGreenlet* p;
  1178. PyObject* run_info = NULL;
  1179. if (nparent == NULL) {
  1180. PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
  1181. return -1;
  1182. }
  1183. if (!PyGreenlet_Check(nparent)) {
  1184. PyErr_SetString(PyExc_TypeError, "parent must be a greenlet");
  1185. return -1;
  1186. }
  1187. for (p=(PyGreenlet*) nparent; p; p=p->parent) {
  1188. if (p == self) {
  1189. PyErr_SetString(PyExc_ValueError, "cyclic parent chain");
  1190. return -1;
  1191. }
  1192. run_info = PyGreenlet_ACTIVE(p) ? p->run_info : NULL;
  1193. }
  1194. if (run_info == NULL) {
  1195. PyErr_SetString(PyExc_ValueError, "parent must not be garbage collected");
  1196. return -1;
  1197. }
  1198. if (PyGreenlet_STARTED(self) && self->run_info != run_info) {
  1199. PyErr_SetString(PyExc_ValueError, "parent cannot be on a different thread");
  1200. return -1;
  1201. }
  1202. p = self->parent;
  1203. self->parent = (PyGreenlet*) nparent;
  1204. Py_INCREF(nparent);
  1205. Py_XDECREF(p);
  1206. return 0;
  1207. }
  1208. static PyObject* green_getframe(PyGreenlet* self, void* c)
  1209. {
  1210. PyObject* result = self->top_frame ? (PyObject*) self->top_frame : Py_None;
  1211. Py_INCREF(result);
  1212. return result;
  1213. }
  1214. static PyObject* green_getstate(PyGreenlet* self)
  1215. {
  1216. PyErr_Format(PyExc_TypeError,
  1217. "cannot serialize '%s' object",
  1218. Py_TYPE(self)->tp_name);
  1219. return NULL;
  1220. }
  1221. /*****************************************************************************
  1222. * C interface
  1223. *
  1224. * These are exported using the CObject API
  1225. */
  1226. static PyGreenlet *
  1227. PyGreenlet_GetCurrent(void)
  1228. {
  1229. if (!STATE_OK) {
  1230. return NULL;
  1231. }
  1232. Py_INCREF(ts_current);
  1233. return ts_current;
  1234. }
  1235. static int
  1236. PyGreenlet_SetParent(PyGreenlet *g, PyGreenlet *nparent)
  1237. {
  1238. if (!PyGreenlet_Check(g)) {
  1239. PyErr_SetString(PyExc_TypeError, "parent must be a greenlet");
  1240. return -1;
  1241. }
  1242. return green_setparent((PyGreenlet*) g, (PyObject *) nparent, NULL);
  1243. }
  1244. static PyGreenlet *
  1245. PyGreenlet_New(PyObject *run, PyGreenlet *parent)
  1246. {
  1247. PyGreenlet* g = NULL;
  1248. g = (PyGreenlet *) PyType_GenericAlloc(&PyGreenlet_Type, 0);
  1249. if (g == NULL) {
  1250. return NULL;
  1251. }
  1252. if (run != NULL) {
  1253. Py_INCREF(run);
  1254. g->run_info = run;
  1255. }
  1256. if (parent != NULL) {
  1257. if (PyGreenlet_SetParent(g, parent)) {
  1258. Py_DECREF(g);
  1259. return NULL;
  1260. }
  1261. } else {
  1262. if ((g->parent = PyGreenlet_GetCurrent()) == NULL) {
  1263. Py_DECREF(g);
  1264. return NULL;
  1265. }
  1266. }
  1267. return g;
  1268. }
  1269. static PyObject *
  1270. PyGreenlet_Switch(PyGreenlet *g, PyObject *args, PyObject *kwargs)
  1271. {
  1272. PyGreenlet *self = (PyGreenlet *) g;
  1273. if (!PyGreenlet_Check(self)) {
  1274. PyErr_BadArgument();
  1275. return NULL;
  1276. }
  1277. if (args == NULL) {
  1278. args = Py_BuildValue("()");
  1279. }
  1280. else {
  1281. Py_INCREF(args);
  1282. }
  1283. if (kwargs != NULL && PyDict_Check(kwargs)) {
  1284. Py_INCREF(kwargs);
  1285. }
  1286. else {
  1287. kwargs = NULL;
  1288. }
  1289. return single_result(g_switch(self, args, kwargs));
  1290. }
  1291. static PyObject *
  1292. PyGreenlet_Throw(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)
  1293. {
  1294. if (!PyGreenlet_Check(self)) {
  1295. PyErr_BadArgument();
  1296. return NULL;
  1297. }
  1298. Py_INCREF(typ);
  1299. Py_XINCREF(val);
  1300. Py_XINCREF(tb);
  1301. return throw_greenlet(self, typ, val, tb);
  1302. }
  1303. /** End C API ****************************************************************/
  1304. static PyMethodDef green_methods[] = {
  1305. {"switch", (PyCFunction)green_switch,
  1306. METH_VARARGS | METH_KEYWORDS, green_switch_doc},
  1307. {"throw", (PyCFunction)green_throw, METH_VARARGS, green_throw_doc},
  1308. {"__getstate__", (PyCFunction)green_getstate, METH_NOARGS, NULL},
  1309. {NULL, NULL} /* sentinel */
  1310. };
  1311. static PyGetSetDef green_getsets[] = {
  1312. {"__dict__", (getter)green_getdict,
  1313. (setter)green_setdict, /*XXX*/ NULL},
  1314. {"run", (getter)green_getrun,
  1315. (setter)green_setrun, /*XXX*/ NULL},
  1316. {"parent", (getter)green_getparent,
  1317. (setter)green_setparent, /*XXX*/ NULL},
  1318. {"gr_frame", (getter)green_getframe,
  1319. NULL, /*XXX*/ NULL},
  1320. {"dead", (getter)green_getdead,
  1321. NULL, /*XXX*/ NULL},
  1322. {"_stack_saved", (getter)green_get_stack_saved,
  1323. NULL, /*XXX*/ NULL},
  1324. {NULL}
  1325. };
  1326. static PyNumberMethods green_as_number = {
  1327. NULL, /* nb_add */
  1328. NULL, /* nb_subtract */
  1329. NULL, /* nb_multiply */
  1330. #if PY_MAJOR_VERSION < 3
  1331. NULL, /* nb_divide */
  1332. #endif
  1333. NULL, /* nb_remainder */
  1334. NULL, /* nb_divmod */
  1335. NULL, /* nb_power */
  1336. NULL, /* nb_negative */
  1337. NULL, /* nb_positive */
  1338. NULL, /* nb_absolute */
  1339. (inquiry)green_bool, /* nb_bool */
  1340. };
  1341. PyTypeObject PyGreenlet_Type = {
  1342. PyVarObject_HEAD_INIT(NULL, 0)
  1343. "greenlet.greenlet", /* tp_name */
  1344. sizeof(PyGreenlet), /* tp_basicsize */
  1345. 0, /* tp_itemsize */
  1346. /* methods */
  1347. (destructor)green_dealloc, /* tp_dealloc */
  1348. 0, /* tp_print */
  1349. 0, /* tp_getattr */
  1350. 0, /* tp_setattr */
  1351. 0, /* tp_compare */
  1352. 0, /* tp_repr */
  1353. &green_as_number, /* tp_as _number*/
  1354. 0, /* tp_as _sequence*/
  1355. 0, /* tp_as _mapping*/
  1356. 0, /* tp_hash */
  1357. 0, /* tp_call */
  1358. 0, /* tp_str */
  1359. 0, /* tp_getattro */
  1360. 0, /* tp_setattro */
  1361. 0, /* tp_as_buffer*/
  1362. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | GREENLET_GC_FLAGS, /* tp_flags */
  1363. "greenlet(run=None, parent=None) -> greenlet\n\n"
  1364. "Creates a new greenlet object (without running it).\n\n"
  1365. " - *run* -- The callable to invoke.\n"
  1366. " - *parent* -- The parent greenlet. The default is the current "
  1367. "greenlet.", /* tp_doc */
  1368. (traverseproc)GREENLET_tp_traverse, /* tp_traverse */
  1369. (inquiry)GREENLET_tp_clear, /* tp_clear */
  1370. 0, /* tp_richcompare */
  1371. offsetof(PyGreenlet, weakreflist), /* tp_weaklistoffset */
  1372. 0, /* tp_iter */
  1373. 0, /* tp_iternext */
  1374. green_methods, /* tp_methods */
  1375. 0, /* tp_members */
  1376. green_getsets, /* tp_getset */
  1377. 0, /* tp_base */
  1378. 0, /* tp_dict */
  1379. 0, /* tp_descr_get */
  1380. 0, /* tp_descr_set */
  1381. offsetof(PyGreenlet, dict), /* tp_dictoffset */
  1382. (initproc)green_init, /* tp_init */
  1383. GREENLET_tp_alloc, /* tp_alloc */
  1384. green_new, /* tp_new */
  1385. GREENLET_tp_free, /* tp_free */
  1386. (inquiry)GREENLET_tp_is_gc, /* tp_is_gc */
  1387. };
  1388. static PyObject* mod_getcurrent(PyObject* self)
  1389. {
  1390. if (!STATE_OK)
  1391. return NULL;
  1392. Py_INCREF(ts_current);
  1393. return (PyObject*) ts_current;
  1394. }
  1395. #if GREENLET_USE_TRACING
  1396. static PyObject* mod_settrace(PyObject* self, PyObject* args)
  1397. {
  1398. int err;
  1399. PyObject* previous;
  1400. PyObject* tracefunc;
  1401. PyGreenlet* current;
  1402. if (!PyArg_ParseTuple(args, "O", &tracefunc))
  1403. return NULL;
  1404. if (!STATE_OK)
  1405. return NULL;
  1406. current = ts_current;
  1407. previous = PyDict_GetItem(current->run_info, ts_tracekey);
  1408. if (previous == NULL)
  1409. previous = Py_None;
  1410. Py_INCREF(previous);
  1411. if (tracefunc == Py_None)
  1412. err = previous != Py_None ? PyDict_DelItem(current->run_info, ts_tracekey) : 0;
  1413. else
  1414. err = PyDict_SetItem(current->run_info, ts_tracekey, tracefunc);
  1415. if (err < 0)
  1416. Py_CLEAR(previous);
  1417. return previous;
  1418. }
  1419. static PyObject* mod_gettrace(PyObject* self)
  1420. {
  1421. PyObject* tracefunc;
  1422. if (!STATE_OK)
  1423. return NULL;
  1424. tracefunc = PyDict_GetItem(ts_current->run_info, ts_tracekey);
  1425. if (tracefunc == NULL)
  1426. tracefunc = Py_None;
  1427. Py_INCREF(tracefunc);
  1428. return tracefunc;
  1429. }
  1430. #endif
  1431. static PyMethodDef GreenMethods[] = {
  1432. {"getcurrent", (PyCFunction)mod_getcurrent, METH_NOARGS, /*XXX*/ NULL},
  1433. #if GREENLET_USE_TRACING
  1434. {"settrace", (PyCFunction)mod_settrace, METH_VARARGS, NULL},
  1435. {"gettrace", (PyCFunction)mod_gettrace, METH_NOARGS, NULL},
  1436. #endif
  1437. {NULL, NULL} /* Sentinel */
  1438. };
  1439. static char* copy_on_greentype[] = {
  1440. "getcurrent",
  1441. "error",
  1442. "GreenletExit",
  1443. #if GREENLET_USE_TRACING
  1444. "settrace",
  1445. "gettrace",
  1446. #endif
  1447. NULL
  1448. };
  1449. #if PY_MAJOR_VERSION >= 3
  1450. #define INITERROR return NULL
  1451. static struct PyModuleDef greenlet_module_def = {
  1452. PyModuleDef_HEAD_INIT,
  1453. "greenlet",
  1454. NULL,
  1455. -1,
  1456. GreenMethods,
  1457. };
  1458. PyMODINIT_FUNC
  1459. PyInit_greenlet(void)
  1460. #else
  1461. #define INITERROR return
  1462. PyMODINIT_FUNC
  1463. initgreenlet(void)
  1464. #endif
  1465. {
  1466. PyObject* m = NULL;
  1467. char** p = NULL;
  1468. PyObject *c_api_object;
  1469. static void *_PyGreenlet_API[PyGreenlet_API_pointers];
  1470. GREENLET_NOINLINE_INIT();
  1471. #if PY_MAJOR_VERSION >= 3
  1472. m = PyModule_Create(&greenlet_module_def);
  1473. #else
  1474. m = Py_InitModule("greenlet", GreenMethods);
  1475. #endif
  1476. if (m == NULL)
  1477. {
  1478. INITERROR;
  1479. }
  1480. if (PyModule_AddStringConstant(m, "__version__", GREENLET_VERSION) < 0)
  1481. {
  1482. INITERROR;
  1483. }
  1484. #if PY_MAJOR_VERSION >= 3
  1485. ts_curkey = PyUnicode_InternFromString("__greenlet_ts_curkey");
  1486. ts_delkey = PyUnicode_InternFromString("__greenlet_ts_delkey");
  1487. #if GREENLET_USE_TRACING
  1488. ts_tracekey = PyUnicode_InternFromString("__greenlet_ts_tracekey");
  1489. ts_event_switch = PyUnicode_InternFromString("switch");
  1490. ts_event_throw = PyUnicode_InternFromString("throw");
  1491. #endif
  1492. #else
  1493. ts_curkey = PyString_InternFromString("__greenlet_ts_curkey");
  1494. ts_delkey = PyString_InternFromString("__greenlet_ts_delkey");
  1495. #if GREENLET_USE_TRACING
  1496. ts_tracekey = PyString_InternFromString("__greenlet_ts_tracekey");
  1497. ts_event_switch = PyString_InternFromString("switch");
  1498. ts_event_throw = PyString_InternFromString("throw");
  1499. #endif
  1500. #endif
  1501. if (ts_curkey == NULL || ts_delkey == NULL)
  1502. {
  1503. INITERROR;
  1504. }
  1505. if (PyType_Ready(&PyGreenlet_Type) < 0)
  1506. {
  1507. INITERROR;
  1508. }
  1509. PyExc_GreenletError = PyErr_NewException("greenlet.error", NULL, NULL);
  1510. if (PyExc_GreenletError == NULL)
  1511. {
  1512. INITERROR;
  1513. }
  1514. #if PY_MAJOR_VERSION >= 3 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5)
  1515. PyExc_GreenletExit = PyErr_NewException("greenlet.GreenletExit",
  1516. PyExc_BaseException, NULL);
  1517. #else
  1518. PyExc_GreenletExit = PyErr_NewException("greenlet.GreenletExit",
  1519. NULL, NULL);
  1520. #endif
  1521. if (PyExc_GreenletExit == NULL)
  1522. {
  1523. INITERROR;
  1524. }
  1525. ts_empty_tuple = PyTuple_New(0);
  1526. if (ts_empty_tuple == NULL)
  1527. {
  1528. INITERROR;
  1529. }
  1530. ts_empty_dict = PyDict_New();
  1531. if (ts_empty_dict == NULL)
  1532. {
  1533. INITERROR;
  1534. }
  1535. ts_current = green_create_main();
  1536. if (ts_current == NULL)
  1537. {
  1538. INITERROR;
  1539. }
  1540. Py_INCREF(&PyGreenlet_Type);
  1541. PyModule_AddObject(m, "greenlet", (PyObject*) &PyGreenlet_Type);
  1542. Py_INCREF(PyExc_GreenletError);
  1543. PyModule_AddObject(m, "error", PyExc_GreenletError);
  1544. Py_INCREF(PyExc_GreenletExit);
  1545. PyModule_AddObject(m, "GreenletExit", PyExc_GreenletExit);
  1546. PyModule_AddObject(m, "GREENLET_USE_GC", PyBool_FromLong(GREENLET_USE_GC));
  1547. PyModule_AddObject(m, "GREENLET_USE_TRACING", PyBool_FromLong(GREENLET_USE_TRACING));
  1548. /* also publish module-level data as attributes of the greentype. */
  1549. for (p=copy_on_greentype; *p; p++) {
  1550. PyObject* o = PyObject_GetAttrString(m, *p);
  1551. if (!o) continue;
  1552. PyDict_SetItemString(PyGreenlet_Type.tp_dict, *p, o);
  1553. Py_DECREF(o);
  1554. }
  1555. /*
  1556. * Expose C API
  1557. */
  1558. /* types */
  1559. _PyGreenlet_API[PyGreenlet_Type_NUM] = (void *) &PyGreenlet_Type;
  1560. /* exceptions */
  1561. _PyGreenlet_API[PyExc_GreenletError_NUM] = (void *) PyExc_GreenletError;
  1562. _PyGreenlet_API[PyExc_GreenletExit_NUM] = (void *) PyExc_GreenletExit;
  1563. /* methods */
  1564. _PyGreenlet_API[PyGreenlet_New_NUM] = (void *) PyGreenlet_New;
  1565. _PyGreenlet_API[PyGreenlet_GetCurrent_NUM] =
  1566. (void *) PyGreenlet_GetCurrent;
  1567. _PyGreenlet_API[PyGreenlet_Throw_NUM] = (void *) PyGreenlet_Throw;
  1568. _PyGreenlet_API[PyGreenlet_Switch_NUM] = (void *) PyGreenlet_Switch;
  1569. _PyGreenlet_API[PyGreenlet_SetParent_NUM] =
  1570. (void *) PyGreenlet_SetParent;
  1571. #ifdef GREENLET_USE_PYCAPSULE
  1572. c_api_object = PyCapsule_New((void *) _PyGreenlet_API, "greenlet._C_API", NULL);
  1573. #else
  1574. c_api_object = PyCObject_FromVoidPtr((void *) _PyGreenlet_API, NULL);
  1575. #endif
  1576. if (c_api_object != NULL)
  1577. {
  1578. PyModule_AddObject(m, "_C_API", c_api_object);
  1579. }
  1580. #if PY_MAJOR_VERSION >= 3
  1581. return m;
  1582. #endif
  1583. }