/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
/* Format with:
* clang-format -i --style=file src/greenlet/greenlet.c
*
*
* Fix missing braces with:
* clang-tidy src/greenlet/greenlet.c -fix -checks="readability-braces-around-statements"
*/
#define GREENLET_MODULE
#include "greenlet.h"
#include "structmember.h"
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wmissing-field-initializers"
#endif
/***********************************************************
A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.
Stack layout for a greenlet:
| ^^^ |
| older data |
| |
stack_stop . |_______________|
. | |
. | greenlet data |
. | in stack |
. * |_______________| . . _____________ stack_copy + stack_saved
. | | | |
. | data | |greenlet data|
. | unrelated | | saved |
. | to | | in heap |
stack_start . | this | . . |_____________| stack_copy
| greenlet |
| |
| newer data |
| vvv |
Note that a greenlet's stack data is typically partly at its correct
place in the stack, and partly saved away in the heap, but always in
the above configuration: two blocks, the more recent one in the heap
and the older one still in the stack (either block may be empty).
Greenlets are chained: each points to the previous greenlet, which is
the one that owns the data currently in the C stack above my
stack_stop. The currently running greenlet is the first element of
this chain. The main (initial) greenlet is the last one. Greenlets
whose stack is entirely in the heap can be skipped from the chain.
The chain is not related to execution order, but only to the order
in which bits of C stack happen to belong to greenlets at a particular
point in time.
The main greenlet doesn't have a stack_stop: it is responsible for the
complete rest of the C stack, and we don't know where it begins. We
use (char*) -1, the largest possible address.
States:
stack_stop == NULL && stack_start == NULL: did not start yet
stack_stop != NULL && stack_start == NULL: already finished
stack_stop != NULL && stack_start != NULL: active
The running greenlet's stack_start is undefined but not NULL.
***********************************************************/
/*** global state ***/
/* In the presence of multithreading, this is a bit tricky:
- ts_current always store a reference to a greenlet, but it is
not really the current greenlet after a thread switch occurred.
- each *running* greenlet uses its run_info field to know which
thread it is attached to. A greenlet can only run in the thread
where it was created. This run_info is a ref to tstate->dict.
- the thread state dict is used to save and restore ts_current,
using the dictionary key 'ts_curkey'.
*/
extern PyTypeObject PyGreenlet_Type;
#if PY_VERSION_HEX >= 0x030700A3
# define GREENLET_PY37 1
#else
# define GREENLET_PY37 0
#endif
#if PY_VERSION_HEX >= 0x30A00B1
/*
Python 3.10 beta 1 changed tstate->use_tracing to a nested cframe member.
See https://github.com/python/cpython/pull/25276
We have to save and restore this as well.
*/
#define TSTATE_USE_TRACING(tstate) (tstate->cframe->use_tracing)
#define GREENLET_USE_CFRAME 1
#else
#define TSTATE_USE_TRACING(tstate) (tstate->use_tracing)
#define GREENLET_USE_CFRAME 0
#endif
#ifndef Py_SET_REFCNT
/* Py_REFCNT and Py_SIZE macros are converted to functions
https://bugs.python.org/issue39573 */
# define Py_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt)
#endif
#ifndef _Py_DEC_REFTOTAL
/* _Py_DEC_REFTOTAL macro has been removed from Python 3.9 by:
https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924
*/
# ifdef Py_REF_DEBUG
# define _Py_DEC_REFTOTAL _Py_RefTotal--
# else
# define _Py_DEC_REFTOTAL
# endif
#endif
/* Weak reference to the switching-to greenlet during the slp switch */
static PyGreenlet* volatile ts_target = NULL;
/* Strong reference to the switching from greenlet after the switch */
static PyGreenlet* volatile ts_origin = NULL;
/* Strong reference to the current greenlet in this thread state */
static PyGreenlet* volatile ts_current = NULL;
/* NULL if error, otherwise args tuple to pass around during slp switch */
static PyObject* volatile ts_passaround_args = NULL;
static PyObject* volatile ts_passaround_kwargs = NULL;
/* Used internally in ``g_switchstack()`` */
#if GREENLET_USE_CFRAME
static int volatile ts__g_switchstack_use_tracing = 0;
#endif
/***********************************************************/
/* Thread-aware routines, switching global variables when needed */
#define STATE_OK \
(ts_current->run_info == PyThreadState_GET()->dict || \
!green_updatecurrent())
static PyObject* ts_curkey;
static PyObject* ts_delkey;
static PyObject* ts_tracekey;
static PyObject* ts_event_switch;
static PyObject* ts_event_throw;
static PyObject* PyExc_GreenletError;
static PyObject* PyExc_GreenletExit;
static PyObject* ts_empty_tuple;
static PyObject* ts_empty_dict;
#define GREENLET_GC_FLAGS Py_TPFLAGS_HAVE_GC
#define GREENLET_tp_alloc PyType_GenericAlloc
#define GREENLET_tp_free PyObject_GC_Del
#define GREENLET_tp_traverse green_traverse
#define GREENLET_tp_clear green_clear
#define GREENLET_tp_is_gc green_is_gc
static void
green_clear_exc(PyGreenlet* g)
{
#if GREENLET_PY37
g->exc_info = NULL;
g->exc_state.exc_type = NULL;
g->exc_state.exc_value = NULL;
g->exc_state.exc_traceback = NULL;
g->exc_state.previous_item = NULL;
#else
g->exc_type = NULL;
g->exc_value = NULL;
g->exc_traceback = NULL;
#endif
}
static PyGreenlet*
green_create_main(void)
{
PyGreenlet* gmain;
PyObject* dict = PyThreadState_GetDict();
if (dict == NULL) {
if (!PyErr_Occurred()) {
PyErr_NoMemory();
}
return NULL;
}
/* create the main greenlet for this thread */
gmain = (PyGreenlet*)PyType_GenericAlloc(&PyGreenlet_Type, 0);
if (gmain == NULL) {
return NULL;
}
gmain->stack_start = (char*)1;
gmain->stack_stop = (char*)-1;
/* GetDict() returns a borrowed reference. Make it strong. */
gmain->run_info = dict;
Py_INCREF(dict);
return gmain;
}
static int
green_updatecurrent(void)
{
PyObject *exc, *val, *tb;
PyThreadState* tstate;
PyGreenlet* current;
PyGreenlet* previous;
PyObject* deleteme;
green_updatecurrent_restart:
/* save current exception */
PyErr_Fetch(&exc, &val, &tb);
/* get ts_current from the active tstate */
tstate = PyThreadState_GET();
if (tstate->dict &&
(current = (PyGreenlet*)PyDict_GetItem(tstate->dict, ts_curkey))) {
/* found -- remove it, to avoid keeping a ref */
Py_INCREF(current);
PyDict_DelItem(tstate->dict, ts_curkey);
}
else {
/* first time we see this tstate */
current = green_create_main();
if (current == NULL) {
Py_XDECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
return -1;
}
}
assert(current->run_info == tstate->dict);
green_updatecurrent_retry:
/* update ts_current as soon as possible, in case of nested switches */
Py_INCREF(current);
previous = ts_current;
ts_current = current;
/* save ts_current as the current greenlet of its own thread */
if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObject*)previous)) {
P
没有合适的资源?快使用搜索试试~ 我知道了~
使用flask开发的网上购物系统.zip
共2000个文件
py:1550个
pyc:273个
txt:90个
需积分: 0 2 下载量 74 浏览量
2023-09-28
16:03:22
上传
评论
收藏 29.7MB ZIP 举报
温馨提示
使用flask开发的网上购物系统.zip
资源推荐
资源详情
资源评论
收起资源包目录
使用flask开发的网上购物系统.zip (2000个子文件)
greenlet.c 64KB
_test_extension.c 5KB
_test_extension_cpp.cpp 3KB
bootstrap.css 143KB
bootstrap.min.css 118KB
bootstrap-theme.css 26KB
bootstrap-theme.min.css 23KB
style.css 7KB
greenlet.h 4KB
greenlet.h 4KB
switch_ppc64_aix.h 4KB
switch_ppc64_linux.h 4KB
slp_platformselect.h 3KB
switch_x86_unix.h 3KB
switch_ppc_aix.h 3KB
switch_sparc_sun_gcc.h 3KB
switch_s390_unix.h 3KB
switch_ppc_linux.h 3KB
switch_ppc_unix.h 3KB
switch_ppc_macosx.h 3KB
switch_amd64_unix.h 3KB
switch_arm32_gcc.h 2KB
switch_x86_msvc.h 2KB
switch_aarch64_gcc.h 2KB
switch_arm32_ios.h 2KB
switch_x64_msvc.h 2KB
switch_x32_unix.h 1KB
switch_mips_unix.h 1KB
switch_csky_gcc.h 1KB
switch_m68k_gcc.h 928B
switch_riscv_unix.h 758B
switch_alpha_unix.h 689B
category_search_commodity_results.html 8KB
wtf.html 8KB
show_category_commodities.html 7KB
commodity_detail.html 7KB
search_commodity_results.html 6KB
index.html 5KB
base.html 5KB
manage_commodities.html 3KB
user.html 3KB
manage_user_orders.html 3KB
profile.html 3KB
address.html 2KB
my_basket.html 2KB
pagination.html 2KB
my_orders.html 2KB
user_store_profile.html 2KB
manage_store_commodities.html 2KB
google.html 2KB
utils.html 1KB
base.html 1KB
store_detail.html 858B
edit_profile.html 779B
unconfirmed.html 453B
login.html 360B
confirm_order.html 351B
edit_store_commodity.html 307B
edit_store_profile.html 307B
edit_address.html 299B
add_address.html 299B
register_store.html 293B
fixes.html 287B
reset_password.html 286B
get_userid.html 280B
register.html 280B
500.html 183B
404.html 169B
INSTALLER 4B
jquery.js 287KB
jquery.min.js 95KB
bootstrap.js 68KB
bootstrap.min.js 36KB
debugger.js 10KB
npm.js 484B
version_info.json 93B
LICENSE 1KB
LICENSE.md 1KB
LICENSE.md 1KB
ICON_LICENSE.md 222B
README.md 64B
METADATA 11KB
selectable.py 230KB
pyparsing.py 221KB
pyparsing.py 221KB
pyparsing.py 221KB
uts46data.py 200KB
uts46data.py 193KB
schema.py 184KB
compiler.py 181KB
elements.py 176KB
session.py 155KB
_php_builtins.py 151KB
base.py 150KB
relationships.py 140KB
lisp.py 138KB
_emoji_codes.py 137KB
mapper.py 136KB
_lasso_builtins.py 131KB
matlab.py 129KB
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
资源评论
天天501
- 粉丝: 596
- 资源: 4666
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 欧阳雨彤202330813009.py
- 基于 Yolov5 的自动贴标IMG,以及许多其他有用的工具
- 基于STM32F103C8T6、LCD1602、AD5206(I2C接口)6路数字电位器的proteus仿真应用设计
- 021315100-2405220913.awb
- 语音分帧与加窗基于MATLAB
- 二层独栋别墅砖混结构D027-两层-10.40&10.30米-施工图.dwg
- 帆软跑马灯制作,附件有制作好的效果
- 本户型为2层独栋别墅D026-两层-13.14&12.84米-施工图.dwg
- 双层别墅图纸有施工图D022-两层-08.70&10.80米-施工图.dwg
- 基于Android的交通事故全责图解设计源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功