1 Star 0 Fork 0

exchange / swoole-src

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
swoole_coroutine.h 6.85 KB
一键复制 编辑 原始数据 按行查看 历史
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinyu Zhu <xyzhu1120@gmail.com> |
| shiguangqi <shiguangqi2008@gmail.com> |
| Twosee <twose@qq.com> |
| Tianfeng Han <rango@swoole.com> |
+----------------------------------------------------------------------+
*/
#pragma once
#include "coroutine_cxx_api.h"
#include "zend_vm.h"
#include "zend_closures.h"
#include <stack>
#define SW_DEFAULT_MAX_CORO_NUM 100000
#define SW_DEFAULT_PHP_STACK_PAGE_SIZE 8192
#define SWOG ((zend_output_globals *) &OG(handlers))
enum sw_coro_hook_type
{
SW_HOOK_TCP = 1u << 1,
SW_HOOK_UDP = 1u << 2,
SW_HOOK_UNIX = 1u << 3,
SW_HOOK_UDG = 1u << 4,
SW_HOOK_SSL = 1u << 5,
SW_HOOK_TLS = 1u << 6,
SW_HOOK_STREAM_FUNCTION = 1u << 7,
SW_HOOK_FILE = 1u << 8,
SW_HOOK_SLEEP = 1u << 9,
SW_HOOK_PROC = 1u << 10,
SW_HOOK_CURL = 1u << 28,
SW_HOOK_BLOCKING_FUNCTION = 1u << 30,
SW_HOOK_ALL = 0x7fffffff ^ SW_HOOK_CURL /* TODO: remove it [v4.6] */
};
struct php_coro_task
{
JMP_BUF *bailout;
zval *vm_stack_top;
zval *vm_stack_end;
zend_vm_stack vm_stack;
size_t vm_stack_page_size;
zend_execute_data *execute_data;
zend_error_handling_t error_handling;
zend_class_entry *exception_class;
zend_object *exception;
zend_output_globals *output_ptr;
/* for array_walk non-reentrancy */
php_swoole_fci *array_walk_fci;
/* for error control `@` */
bool in_silence;
int ori_error_reporting;
int tmp_error_reporting;
swoole::Coroutine *co;
std::stack<php_swoole_fci *> *defer_tasks;
long pcid;
zend_object *context;
int64_t last_msec;
zend_bool enable_scheduler;
};
struct php_coro_args
{
zend_fcall_info_cache *fci_cache;
zval *argv;
uint32_t argc;
};
// TODO: remove php coro context
struct php_coro_context
{
zval coro_params;
zval *current_coro_return_value_ptr;
void *private_data;
swTimer_node *timer;
php_coro_task *current_task;
};
SW_EXTERN_C_BEGIN
PHP_METHOD(swoole_coroutine_scheduler, set);
SW_EXTERN_C_END
namespace swoole
{
namespace coroutine
{
struct Config
{
uint64_t max_num;
long hook_flags;
bool enable_preemptive_scheduler;
};
}
class PHPCoroutine
{
public:
static const uint8_t MAX_EXEC_MSEC = 10;
static coroutine::Config config;
static void init();
static void deactivate(void *ptr);
static void shutdown();
static long create(zend_fcall_info_cache *fci_cache, uint32_t argc, zval *argv);
static void defer(php_swoole_fci *fci);
static bool enable_hook(int flags);
static bool disable_hook();
static void interrupt_thread_stop();
// TODO: remove old coro APIs (Manual)
static void yield_m(zval *return_value, php_coro_context *sw_php_context);
static int resume_m(php_coro_context *sw_current_context, zval *retval, zval *coro_retval);
static inline long get_cid()
{
return sw_likely(active) ? Coroutine::get_current_cid() : -1;
}
static inline long get_pcid(long cid = 0)
{
php_coro_task *task = cid == 0 ? get_task() : get_task_by_cid(cid);
return sw_likely(task) ? task->pcid : 0;
}
static inline long get_elapsed(long cid = 0)
{
return sw_likely(active) ? Coroutine::get_elapsed(cid) : -1;
}
static inline php_coro_task* get_task()
{
php_coro_task *task = (php_coro_task *) Coroutine::get_current_task();
return task ? task : &main_task;
}
static inline php_coro_task* get_origin_task(php_coro_task *task)
{
Coroutine *co = task->co->get_origin();
return co ? (php_coro_task *) co->get_task() : &main_task;
}
static inline php_coro_task* get_task_by_cid(long cid)
{
return cid == -1 ? &main_task : (php_coro_task *) Coroutine::get_task_by_cid(cid);
}
static inline uint64_t get_max_num()
{
return config.max_num;
}
static inline void set_max_num(uint64_t n)
{
config.max_num = n;
}
static inline bool is_schedulable(php_coro_task *task)
{
return task->enable_scheduler && (swTimer_get_absolute_msec() - task->last_msec > MAX_EXEC_MSEC);
}
static inline bool enable_scheduler()
{
php_coro_task *task = (php_coro_task *) Coroutine::get_current_task();
if (task && task->enable_scheduler == 0)
{
task->enable_scheduler = 1;
return true;
}
return false;
}
static inline bool disable_scheduler()
{
php_coro_task *task = (php_coro_task *) Coroutine::get_current_task();
if (task && task->enable_scheduler == 1)
{
task->enable_scheduler = 0;
return true;
}
return false;
}
protected:
static bool active;
static php_coro_task main_task;
static bool interrupt_thread_running;
static pthread_t interrupt_thread_id;
static void activate();
static inline void vm_stack_init(void);
static inline void vm_stack_destroy(void);
static inline void save_vm_stack(php_coro_task *task);
static inline void restore_vm_stack(php_coro_task *task);
static inline void save_og(php_coro_task *task);
static inline void restore_og(php_coro_task *task);
static inline void save_task(php_coro_task *task);
static inline void restore_task(php_coro_task *task);
static void on_yield(void *arg);
static void on_resume(void *arg);
static void on_close(void *arg);
static void main_func(void *arg);
static void interrupt_thread_start();
static void interrupt_thread_loop();
static inline void record_last_msec(php_coro_task *task)
{
if (interrupt_thread_running)
{
task->last_msec = swTimer_get_absolute_msec();
}
}
};
}
/**
* for gdb
*/
zend_executor_globals* php_swoole_get_executor_globals();
1
https://gitee.com/exchange_96/swoole-src.git
git@gitee.com:exchange_96/swoole-src.git
exchange_96
swoole-src
swoole-src
master

搜索帮助