diff --git a/ext-src/php_swoole_http_server.h b/ext-src/php_swoole_http_server.h index 4d025788af..22855ccfcb 100644 --- a/ext-src/php_swoole_http_server.h +++ b/ext-src/php_swoole_http_server.h @@ -48,35 +48,35 @@ int swoole_http2_server_goaway(swoole::http::Context *ctx, static inline void http_server_add_server_array(HashTable *ht, zend_string *key, const char *value) { zval tmp; ZVAL_STRING(&tmp, value); - zend_hash_add(ht, key, &tmp); + zend_hash_add_new(ht, key, &tmp); } static inline void http_server_add_server_array(HashTable *ht, zend_string *key, const char *value, size_t length) { zval tmp; ZVAL_STRINGL(&tmp, value, length); - zend_hash_add(ht, key, &tmp); + zend_hash_add_new(ht, key, &tmp); } static inline void http_server_add_server_array(HashTable *ht, zend_string *key, zend_long value) { zval tmp; ZVAL_LONG(&tmp, value); - zend_hash_add(ht, key, &tmp); + zend_hash_add_new(ht, key, &tmp); } static inline void http_server_add_server_array(HashTable *ht, zend_string *key, double value) { zval tmp; ZVAL_DOUBLE(&tmp, value); - zend_hash_add(ht, key, &tmp); + zend_hash_add_new(ht, key, &tmp); } static inline void http_server_add_server_array(HashTable *ht, zend_string *key, zend_string *value) { zval tmp; ZVAL_STR(&tmp, value); - zend_hash_add(ht, key, &tmp); + zend_hash_add_new(ht, key, &tmp); } static inline void http_server_add_server_array(HashTable *ht, zend_string *key, zval *value) { - zend_hash_add(ht, key, value); + zend_hash_add_new(ht, key, value); } static inline void http_server_set_object_fd_property(zend_object *object, zend_class_entry *ce, long fd) { diff --git a/ext-src/swoole_server.cc b/ext-src/swoole_server.cc index 7c49e90871..c554af1b89 100644 --- a/ext-src/swoole_server.cc +++ b/ext-src/swoole_server.cc @@ -139,8 +139,10 @@ static zend_class_entry *swoole_server_task_result_ce; static zend_object_handlers swoole_server_task_result_handlers; static SW_THREAD_LOCAL zval swoole_server_instance; +#ifdef SW_THREAD static SW_THREAD_LOCAL WorkerFn worker_thread_fn; static SW_THREAD_LOCAL std::vector swoole_server_port_properties; +#endif static sw_inline ServerObject *server_fetch_object(zend_object *obj) { return (ServerObject *) ((char *) obj - swoole_server_handlers.offset); @@ -2372,6 +2374,7 @@ static PHP_METHOD(swoole_server, set) { zend_long v = zval_get_long(ztmp); serv->message_queue_key = SW_MAX(0, SW_MIN(v, INT64_MAX)); } +#ifdef SW_THREAD // bootstrap if (php_swoole_array_get_value(vht, "bootstrap", ztmp)) { zend::object_set(ZEND_THIS, ZEND_STRL("bootstrap"), ztmp); @@ -2384,6 +2387,7 @@ static PHP_METHOD(swoole_server, set) { } else { ZVAL_NULL(&server_object->init_arguments); } +#endif if (serv->task_enable_coroutine && (serv->task_ipc_mode == Server::TASK_IPC_MSGQUEUE || serv->task_ipc_mode == Server::TASK_IPC_PREEMPTIVE)) { diff --git a/include/swoole_server.h b/include/swoole_server.h index 36f2373b7f..d9ccf586a3 100644 --- a/include/swoole_server.h +++ b/include/swoole_server.h @@ -325,6 +325,8 @@ struct ListenPort { void close(); bool import(int sock); const char *get_protocols(); + int create_socket(Server *server); + void close_socket(); #ifdef SW_USE_OPENSSL bool ssl_create_context(SSLContext *context); diff --git a/src/server/master.cc b/src/server/master.cc index b77fb64639..21a2029f2d 100644 --- a/src/server/master.cc +++ b/src/server/master.cc @@ -1706,29 +1706,6 @@ int Server::add_systemd_socket() { return count; } -static bool Server_create_socket(ListenPort *ls) { - ls->socket = make_socket( - ls->type, ls->is_dgram() ? SW_FD_DGRAM_SERVER : SW_FD_STREAM_SERVER, SW_SOCK_CLOEXEC | SW_SOCK_NONBLOCK); - if (!ls->socket) { - return false; - } -#if defined(SW_SUPPORT_DTLS) && defined(HAVE_KQUEUE) - if (ls->is_dtls()) { - ls->socket->set_reuse_port(); - } -#endif - - if (ls->socket->bind(ls->host, &ls->port) < 0) { - swoole_set_last_error(errno); - ls->socket->free(); - return false; - } - - ls->socket->info.assign(ls->type, ls->host, ls->port); - - return true; -} - ListenPort *Server::add_port(SocketType type, const char *host, int port) { if (session_list) { swoole_error_log(SW_LOG_ERROR, SW_ERROR_WRONG_OPERATION, "must add port before server is created"); @@ -1786,7 +1763,7 @@ ListenPort *Server::add_port(SocketType type, const char *host, int port) { } #endif - if (!Server_create_socket(ls)) { + if (ls->create_socket(this) < 0) { swoole_set_last_error(errno); return nullptr; } diff --git a/src/server/port.cc b/src/server/port.cc index 89902ae709..af037bef3b 100644 --- a/src/server/port.cc +++ b/src/server/port.cc @@ -792,4 +792,56 @@ size_t ListenPort::get_connection_num() const { } } +int ListenPort::create_socket(Server *server) { + if (socket) { +#if defined(__linux__) && defined(HAVE_REUSEPORT) + if (server->enable_reuse_port) { + close_socket(); + } else +#endif + { + return SW_OK; + } + } + + socket = make_socket( + type, is_dgram() ? SW_FD_DGRAM_SERVER : SW_FD_STREAM_SERVER, SW_SOCK_CLOEXEC | SW_SOCK_NONBLOCK); + if (socket == nullptr) { + swoole_set_last_error(errno); + return SW_ERR; + } + +#if defined(SW_SUPPORT_DTLS) && defined(HAVE_KQUEUE) + if (ls->is_dtls()) { + socket->set_reuse_port(); + } +#endif + +#if defined(__linux__) && defined(HAVE_REUSEPORT) + if (server->enable_reuse_port) { + if (socket->set_reuse_port() < 0) { + socket->free(); + return SW_ERR; + } + } +#endif + + if (socket->bind(host, &port) < 0) { + swoole_set_last_error(errno); + socket->free(); + return SW_ERR; + } + + socket->info.assign(type, host, port); + return SW_OK; +} + +void ListenPort::close_socket() { + if (::close(socket->fd) < 0) { + swoole_sys_warning("close(%d) failed", socket->fd); + } + delete socket; + socket = nullptr; +} + } // namespace swoole diff --git a/src/server/reactor_process.cc b/src/server/reactor_process.cc index 6ef8d84e67..d4c9370d33 100644 --- a/src/server/reactor_process.cc +++ b/src/server/reactor_process.cc @@ -24,10 +24,6 @@ static int ReactorProcess_onPipeRead(Reactor *reactor, Event *event); static int ReactorProcess_onClose(Reactor *reactor, Event *event); static void ReactorProcess_onTimeout(Timer *timer, TimerNode *tnode); -#ifdef HAVE_REUSEPORT -static int ReactorProcess_reuse_port(ListenPort *ls); -#endif - static bool Server_is_single(Server *serv) { return (serv->worker_num == 1 && serv->task_worker_num == 0 && serv->max_request == 0 && serv->user_worker_list.empty()); @@ -39,24 +35,19 @@ int Server::start_reactor_processes() { // listen TCP if (have_stream_sock == 1) { for (auto ls : ports) { - if (ls->is_dgram()) { - continue; - } -#ifdef HAVE_REUSEPORT - if (enable_reuse_port) { - if (::close(ls->socket->fd) < 0) { - swoole_sys_warning("close(%d) failed", ls->socket->fd); - } - delete ls->socket; - ls->socket = nullptr; - continue; - } else + if (ls->is_stream()) { +#if defined(__linux__) && defined(HAVE_REUSEPORT) + if (!enable_reuse_port) { #endif - { - // listen server socket - if (ls->listen() < 0) { - return SW_ERR; + // listen server socket + if (ls->listen() < 0) { + return SW_ERR; + } +#if defined(__linux__) && defined(HAVE_REUSEPORT) + } else { + ls->close_socket(); } +#endif } } } @@ -194,12 +185,16 @@ int Server::worker_main_loop(ProcessPool *pool, Worker *worker) { serv->worker_signal_init(); for (auto ls : serv->ports) { -#ifdef HAVE_REUSEPORT +#if defined(__linux__) and defined(HAVE_REUSEPORT) if (ls->is_stream() && serv->enable_reuse_port) { - if (ReactorProcess_reuse_port(ls) < 0) { + if (ls->create_socket(serv) < 0) { swoole_event_free(); return SW_ERR; } + + if (ls->listen() < 0) { + return SW_ERR; + } } #endif if (reactor->add(ls->socket, SW_EVENT_READ) < 0) { @@ -350,21 +345,4 @@ static void ReactorProcess_onTimeout(Timer *timer, TimerNode *tnode) { ReactorProcess_onClose(reactor, ¬ify_ev); }); } - -#ifdef HAVE_REUSEPORT -static int ReactorProcess_reuse_port(ListenPort *ls) { - ls->socket = swoole::make_socket( - ls->type, ls->is_dgram() ? SW_FD_DGRAM_SERVER : SW_FD_STREAM_SERVER, SW_SOCK_CLOEXEC | SW_SOCK_NONBLOCK); - if (ls->socket->set_reuse_port() < 0) { - ls->socket->free(); - return SW_ERR; - } - if (ls->socket->bind(ls->host, &ls->port) < 0) { - ls->socket->free(); - return SW_ERR; - } - return ls->listen(); -} -#endif - } // namespace swoole