swoole的TCP服务器实现-swoole_server创建过程( 二 )

<= 0)//系统自动绑定端口号和主机名,这里不展开讨论,需要了解的请自行去了解{swoole_php_fatal_error(E_ERROR, "failed to add systemd socket.");return;}}else//大众化的场景,即指定了端口号和主机名信息{//创建server socket,并且bind端口号信息,后面专门展开分析swListenPort *port = swServer_add_port(serv, sock_type, serv_host, serv_port);if (!port){zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "failed to listen server port[%s:%ld]. Error: %s[%d].",serv_host, serv_port, strerror(errno), errno);return;}}//PHP扩展的API,getThis()用于获取PHP当前的对象,也就是swoole_serverzval *server_object = getThis();#ifdef HAVE_PCREzval *connection_iterator_object;SW_MAKE_STD_ZVAL(connection_iterator_object);object_init_ex(connection_iterator_object, swoole_connection_iterator_class_entry_ptr);zend_update_property(swoole_server_class_entry_ptr, server_object, ZEND_STRL("connections"), connection_iterator_object TSRMLS_CC);swConnectionIterator *i = emalloc(sizeof(swConnectionIterator));bzero(i, sizeof(swConnectionIterator));i->serv = serv;swoole_set_object(connection_iterator_object, i);#endif//设置swoole_server对象的属性值zend_update_property_stringl(swoole_server_class_entry_ptr, server_object, ZEND_STRL("host"), serv_host, host_len TSRMLS_CC);//设置swoole_server对象的属性值zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("port"), (long) serv->listen_list->port TSRMLS_CC);//设置swoole_server对象的属性值zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("mode"), serv->factory_mode TSRMLS_CC);//设置swoole_server对象的属性值zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("type"), sock_type TSRMLS_CC);//缓存当前server对象,这里的key为swoole_server对象在PHP内部的索引值,而value为serv对象,这里可以最多缓存10000000个对象,缓存空间按2倍去逐步扩容swoole_set_object(server_object, serv);//下述是server监听多端口的逻辑,不做具体分析zval *ports;SW_ALLOC_INIT_ZVAL(ports);array_init(ports);server_port_list.zports = ports;#ifdef HT_ALLOW_COW_VIOLATIONHT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(ports));#endifswListenPort *ls;LL_FOREACH(serv->listen_list, ls){php_swoole_server_add_port(serv, ls TSRMLS_CC);}//设置swoole_server的属性值zend_update_property(swoole_server_class_entry_ptr, server_object, ZEND_STRL("ports"), ports TSRMLS_CC);
//初始化swServer和设置默认值void swServer_init(swServer *serv){//swoole的初始化,这里也有比较多的内容,单独在下面进行分析swoole_init();//swServer的空间初始化,初始化为0bzero(serv, sizeof(swServer));//初始化server的工作模式,这里默认为基础模式,关于这里的定义,后续专门分析serv->factory_mode = SW_MODE_BASE;//设置server的reactor个个数,个数取SW_REACTOR_NUM和SW_REACTOR_MAX_THREAD的最大值,目前代码中SW_REACTOR_NUM的定义为CPU的个数,SW_REACTOR_MAX_THREAD定义的值为8serv->reactor_num = SW_REACTOR_NUM > SW_REACTOR_MAX_THREAD ? SW_REACTOR_MAX_THREAD : SW_REACTOR_NUM;//server的调度模式,关于这里的定义,后续专门分析serv->dispatch_mode = SW_DISPATCH_FDMOD;//server的工作进程个数,默认取CPU的个数serv->worker_num = SW_CPU_NUM;//server最大可以打开的文件个数,这里应该理解为最大连接数,取SwooleG.max_sockets和SW_SESSION_LIST_SIZE的最大值,其中SW_SESSION_LIST_SIZE值为1024*1024,而max_sockets取的是系统的软限制serv->max_connection = SwooleG.max_sockets < SW_SESSION_LIST_SIZE ? SwooleG.max_sockets : SW_SESSION_LIST_SIZE;//设置worker进程的最大任务数,默认为0,一个worker进程在处理完超过此数值的任务后将自动退出,进程退出后会释放所有内存和资源,用于解决内存泄露的,这里初始化为0 。serv->max_request = 0;//server的最大等待时间,设置为30s,这个只是一个常量,应该在很多地方会用到,用来设置超时时间serv->max_wait_time = SW_WORKER_MAX_WAIT_TIME;//http server的配置,后面用到了再看serv->http_parse_post = 1;//http server上传文件的目录,这里取的是/tmp目录serv->upload_tmp_dir = sw_strdup("/tmp");//server的心跳检测相关serv->heartbeat_idle_time = SW_HEARTBEAT_IDLE;//心跳存活最大时间serv->heartbeat_check_interval = SW_HEARTBEAT_CHECK;//心跳定时侦查时间//server的buffer大小,这里有进和出的buffer,具体用到了再看,SW_BUFFER_INPUT_SIZE和SW_BUFFER_OUTPUT_SIZE的值都为2Mserv->buffer_input_size = SW_BUFFER_INPUT_SIZE;serv->buffer_output_size = SW_BUFFER_OUTPUT_SIZE;//设置task进程和worker进程的通信方式,这里取默认值为unix socket的方式serv->task_ipc_mode = SW_TASK_IPC_UNIXSOCK;//从内存池申请空间且初始化全局变量swServerStatsserv->stats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats));if (serv->stats == NULL){swError("[Master] Fatal Error: failed to allocate memory for swServer->stats.");}//从内存池申请空间且初始化全局变量swServerGSserv->gs = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS));if (serv->gs == NULL){swError("[Master] Fatal Error: failed to allocate memory for swServer->gs.");}//全局变量设置属性值serv,取已经初始化好的servSwooleG.serv = serv;}