Files
php-src/Zend/zend_fibers.h
Aaron Piotrowski 3939c9b07e Add internal Fiber API (#7045)
This additional internal fiber API creates and manipulates a Fiber object, allowing any internal function to start, resume, or suspend a fiber. The existing zend_fiber_context API allows custom C-based fiber creation using the bundled switching context, but does not interact with the PHP VM. This API behaves the same as calling Fiber object methods from user code, switching EGs, and triggering the fiber switch observer. In general, the Fiber object methods call these new API methods.
2021-05-27 08:33:40 +02:00

117 lines
4.3 KiB
C

/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Aaron Piotrowski <aaron@trowski.com> |
| Martin Schröder <m.schroeder2007@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_FIBERS_H
#define ZEND_FIBERS_H
#include "zend_API.h"
#include "zend_types.h"
BEGIN_EXTERN_C()
void zend_register_fiber_ce(void);
void zend_fiber_init(void);
extern ZEND_API zend_class_entry *zend_ce_fiber;
typedef struct _zend_fiber_context zend_fiber_context;
typedef void (*zend_fiber_coroutine)(zend_fiber_context *context);
typedef struct _zend_fiber_stack {
void *pointer;
size_t size;
#ifdef HAVE_VALGRIND
int valgrind;
#endif
#ifdef __SANITIZE_ADDRESS__
const void *prior_pointer;
size_t prior_size;
#endif
} zend_fiber_stack;
typedef struct _zend_fiber_context {
void *self;
void *caller;
zend_fiber_coroutine function;
zend_fiber_stack stack;
} zend_fiber_context;
typedef struct _zend_fiber {
/* Fiber PHP object handle. */
zend_object std;
/* Status of the fiber, one of the ZEND_FIBER_STATUS_* constants. */
zend_uchar status;
/* Callback and info / cache to be used when fiber is started. */
zend_fcall_info fci;
zend_fcall_info_cache fci_cache;
/* Context of this fiber, will be initialized during call to Fiber::start(). */
zend_fiber_context context;
/* Current Zend VM execute data being run by the fiber. */
zend_execute_data *execute_data;
/* Frame on the bottom of the fiber vm stack. */
zend_execute_data *stack_bottom;
/* Exception to be thrown from Fiber::suspend(). */
zval *exception;
/* Storage for temporaries and fiber return value. */
zval value;
} zend_fiber;
static const zend_uchar ZEND_FIBER_STATUS_INIT = 0x0;
static const zend_uchar ZEND_FIBER_STATUS_SUSPENDED = 0x1;
static const zend_uchar ZEND_FIBER_STATUS_RUNNING = 0x2;
static const zend_uchar ZEND_FIBER_STATUS_RETURNED = 0x4;
static const zend_uchar ZEND_FIBER_STATUS_THREW = 0x8;
static const zend_uchar ZEND_FIBER_STATUS_SHUTDOWN = 0x10;
static const zend_uchar ZEND_FIBER_STATUS_BAILOUT = 0x20;
static const zend_uchar ZEND_FIBER_STATUS_FINISHED = 0x2c;
/* These functions create and manipulate a Fiber object, allowing any internal function to start, resume, or suspend a fiber. */
ZEND_API zend_fiber *zend_fiber_create(const zend_fcall_info *fci, const zend_fcall_info_cache *fci_cache);
ZEND_API void zend_fiber_start(zend_fiber *fiber, zval *params, uint32_t param_count, zend_array *named_params, zval *return_value);
ZEND_API void zend_fiber_suspend(zval *value, zval *return_value);
ZEND_API void zend_fiber_resume(zend_fiber *fiber, zval *value, zval *return_value);
ZEND_API void zend_fiber_throw(zend_fiber *fiber, zval *exception, zval *return_value);
/* These functions may be used to create custom fibers (coroutines) using the bundled fiber switching context. */
ZEND_API zend_bool zend_fiber_init_context(zend_fiber_context *context, zend_fiber_coroutine coroutine, size_t stack_size);
ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context);
ZEND_API void zend_fiber_switch_context(zend_fiber_context *to);
ZEND_API void zend_fiber_suspend_context(zend_fiber_context *current);
#define ZEND_FIBER_GUARD_PAGES 1
#define ZEND_FIBER_DEFAULT_C_STACK_SIZE (4096 * (((sizeof(void *)) < 8) ? 256 : 512))
#define ZEND_FIBER_VM_STACK_SIZE (1024 * sizeof(zval))
END_EXTERN_C()
#endif