You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2012 lines
58KB

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