PHP内核源码阅读过程(三)

int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint32_t num_additional_modules);

 

一、PHP_OS 操作系统类型名字

php_os = PHP_OS;

PHP_OS是由configure生成的,其生成代码如下

PHP_OS=`uname | xargs`

cat >>confdefs.h <<_ACEOF
#define PHP_OS "$PHP_OS"
_ACEOF

也即执行linux命令: uname | xargs

执行结果如下

[root@localhost ~]# uname | xargs
Linux
module_shutdown = 0;
module_startup = 1;
sapi_initialize_empty_request();
sapi_activate();

二、sapi_initialize_empty_request 初始化本次请求的结构。

这个函数其实很简单,给一些变量初始化赋值

# define SG(v) (sapi_globals.v)
extern SAPI_API sapi_globals_struct sapi_globals;

SAPI_API void sapi_initialize_empty_request(void)
{
	SG(server_context) = NULL;
	SG(request_info).request_method = NULL;
	SG(request_info).auth_digest = SG(request_info).auth_user = SG(request_info).auth_password = NULL;
}
	

在之后的源码中,会大量看到类似这种SG的宏,这个其实就是各种全局结构的缩写。

三、sapi_activate 读取本次请求

由于我们是以cli方式启动的,所以这个函数调用,内部其实不会有什么变化, 内部的逻辑都不会调用。

四、php_output_startup 初始化输出

PHPAPI void php_output_startup(void)
{
	ZEND_INIT_MODULE_GLOBALS(output, php_output_init_globals, NULL);
	zend_hash_init(&php_output_handler_aliases, 8, NULL, NULL, 1);
	zend_hash_init(&php_output_handler_conflicts, 8, NULL, NULL, 1);
	zend_hash_init(&php_output_handler_reverse_conflicts, 8, NULL, reverse_conflict_dtor, 1);
	php_output_direct = php_output_stdout;
}

第一行是初始化output_globals这个全局变量,这个变量的类型是zend_output_globals

#define ZEND_BEGIN_MODULE_GLOBALS(module_name)		\
	typedef struct _zend_##module_name##_globals {
#define ZEND_END_MODULE_GLOBALS(module_name)		\
	} zend_##module_name##_globals;

ZEND_BEGIN_MODULE_GLOBALS(output)
	zend_stack handlers;
	php_output_handler *active;
	php_output_handler *running;
	const char *output_start_filename;
	int output_start_lineno;
	int flags;
ZEND_END_MODULE_GLOBALS(output)

后面三行初始化三个array:

1. php_output_handler_aliases: 自定义输出函数列表

2. php_output_handler_conflicts:用来检查“自定义输出接口”重复的工具

3. php_output_handler_reverse_conflicts:目前内核未使用

最后一行将标准输出作为直接输出的方法。

static size_t php_output_stdout(const char *str, size_t str_len)
{
	fwrite(str, 1, str_len, stdout);
	return str_len;
}

五、php_startup_ticks 初始化定时器

struct st_tick_function
{
	void (*func)(int, void *);
	void *arg;
};

int php_startup_ticks(void)
{
	zend_llist_init(&PG(tick_functions), sizeof(struct st_tick_function), NULL, 1);
	return SUCCESS;
}

此定时器不同于通常意义的定时器,这个没有时间间隔的概念,每次只要调用,列表里面的成员都将调用一遍。

ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t func, void *arg)
{
	zend_llist_element *element;

	for (element=l->head; element; element=element->next) {
		func(element->data, arg);
	}
}

static void php_tick_iterator(void *d, void *arg)
{
	struct st_tick_function *data = (struct st_tick_function *)d;
	data->func(*((int *)arg), data->arg);
}

void php_run_ticks(int count)
{
	zend_llist_apply_with_argument(&PG(tick_functions), (llist_apply_with_arg_func_t) php_tick_iterator, &count);
}

六、gc_globals_ctor 全局gc初始化,关于gc又是一个大话题,这里不展开。

void gc_globals_ctor(void)
{
	gc_globals_ctor_ex(&gc_globals);
}

static void gc_globals_ctor_ex(zend_gc_globals *gc_globals)
{
	gc_globals->gc_enabled = 0;
	gc_globals->gc_active = 0;
	gc_globals->gc_protected = 1;
	gc_globals->gc_full = 0;

	gc_globals->buf = NULL;
	gc_globals->unused = GC_INVALID;
	gc_globals->first_unused = GC_INVALID;
	gc_globals->gc_threshold = GC_INVALID;
	gc_globals->buf_size = GC_INVALID;
	gc_globals->num_roots = 0;

	gc_globals->gc_runs = 0;
	gc_globals->collected = 0;
}

七、zend_startup 系统核心部分的初始化下一次再写。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值