static PHP_METHOD(swoole_process, signal) { zval *callback = NULL; long signo = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &signo, &callback) == FAILURE) { return; } if (!SWOOLE_G(cli)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "cannot use swoole_process::signal here."); RETURN_FALSE; } if (SwooleGS->start) { if (signo == SIGTERM || signo == SIGALRM) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot use swoole_process::signal in swoole_server."); RETURN_FALSE; } } if (callback == NULL || ZVAL_IS_NULL(callback)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "no callback."); RETURN_FALSE; } char *func_name; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); sw_zval_add_ref(&callback); signal_callback[signo] = callback; #if PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4 SwooleG.use_signalfd = 1; #else SwooleG.use_signalfd = 0; #endif php_swoole_check_reactor(); /** * for swSignalfd_setup */ SwooleG.main_reactor->check_signalfd = 1; swSignal_add(signo, php_swoole_onSignal); RETURN_TRUE; }
static PHP_METHOD(swoole_process, __construct) { zend_bool redirect_stdin_and_stdout = 0; long create_pipe = 1; zval *callback; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bl", &callback, &redirect_stdin_and_stdout, &create_pipe) == FAILURE) { RETURN_FALSE; } char *func_name = NULL; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); swWorker *process = emalloc(sizeof(swWorker)); bzero(process, sizeof(swWorker)); process->id = php_swoole_worker_round_id++; if (php_swoole_worker_round_id == 0) { php_swoole_worker_round_id = 1; } if (redirect_stdin_and_stdout) { process->redirect_stdin = 1; process->redirect_stdout = 1; process->redirect_stderr = 1; create_pipe = 1; } if (create_pipe > 0) { swPipe *_pipe = emalloc(sizeof(swWorker)); int socket_type = create_pipe == 1 ? SOCK_STREAM : SOCK_DGRAM; if (swPipeUnsock_create(_pipe, 1, socket_type) < 0) { RETURN_FALSE; } process->pipe_object = _pipe; process->pipe_master = _pipe->getFd(_pipe, SW_PIPE_MASTER); process->pipe_worker = _pipe->getFd(_pipe, SW_PIPE_WORKER); process->pipe = process->pipe_master; zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("pipe"), process->pipe_master TSRMLS_CC); } swoole_set_object(getThis(), process); zend_update_property(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("callback"), callback TSRMLS_CC); }
static PHP_METHOD( swoole_websocket_server, on) { zval *callback; zval *event_name; if (SwooleGS->start > 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server is running. Unable to set event callback now."); RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &event_name, &callback) == FAILURE) { return; } swServer *serv = swoole_get_object(getThis()); char *func_name = NULL; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); #if PHP_MAJOR_VERSION >= 7 zval *callback_copy = emalloc(sizeof(zval)); memcpy(callback_copy, callback, sizeof(zval)); callback = callback_copy; #endif serv->open_websocket_protocol = 1; if (strncasecmp("open", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) { sw_zval_add_ref(&callback); websocket_callbacks[0] = callback; } else if (strncasecmp("message", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) { sw_zval_add_ref(&callback); websocket_callbacks[1] = callback; } else { zval *obj = getThis(); sw_zend_call_method_with_2_params(&obj, swoole_http_server_class_entry_ptr, NULL, "on", &return_value, event_name, callback); } }
long php_swoole_add_timer(int ms, zval *callback, zval *param, int is_tick TSRMLS_DC) { if (ms > 86400000) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The given parameters is too big."); return SW_ERR; } char *func_name = NULL; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Function '%s' is not callable", func_name); efree(func_name); return SW_ERR; } efree(func_name); if (SwooleGS->start > 0 && swIsTaskWorker()) { swoole_php_error(E_WARNING, "cannot use swoole_server->after in task worker."); } swTimer_callback *cb = emalloc(sizeof(swTimer_callback)); cb->data = param; cb->callback = callback; if (is_tick) { cb->type = SW_TIMER_TICK; } else { cb->type = SW_TIMER_AFTER; } php_swoole_check_reactor(); php_swoole_check_timer(ms); sw_zval_add_ref(&cb->callback); if (cb->data) { sw_zval_add_ref(&cb->data); } return SwooleG.timer.add(&SwooleG.timer, ms, is_tick, cb); }
static PHP_METHOD(swoole_server_port, on) { char *name = NULL; zend_size_t len, i; zval *cb; if (SwooleGS->start > 0) { swoole_php_fatal_error(E_WARNING, "Server is running. Unable to set event callback now."); RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sz", &name, &len, &cb) == FAILURE) { return; } #ifdef PHP_SWOOLE_CHECK_CALLBACK char *func_name = NULL; if (!sw_zend_is_callable(cb, 0, &func_name TSRMLS_CC)) { swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); efree(func_name); return; } efree(func_name); #endif swoole_server_port_property *property = swoole_get_property(getThis(), 0); swListenPort *port = swoole_get_object(getThis()); if (!port->ptr) { port->ptr = property; } char *callback_name[PHP_SERVER_CALLBACK_NUM] = { "Connect", "Receive", "Close", "Packet", "Start", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Request", "HandShake", "Open", "Message", }; char property_name[128]; int l_property_name = 0; memcpy(property_name, "on", 2); for (i = 0; i < PHP_SERVER_CALLBACK_NUM; i++) { if (callback_name[i] == NULL) { continue; } if (strncasecmp(callback_name[i], name, len) == 0) { memcpy(property_name + 2, callback_name[i], len); l_property_name = len + 2; property_name[l_property_name] = '\0'; zend_update_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, cb TSRMLS_CC); property->callbacks[i] = sw_zend_read_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, 0 TSRMLS_CC); sw_copy_to_stack(property->callbacks[i], property->_callbacks[i]); if (i == SW_SERVER_CB_onConnect && SwooleG.serv->onConnect == NULL) { SwooleG.serv->onConnect = php_swoole_onConnect; } else if (i == SW_SERVER_CB_onClose && SwooleG.serv->onClose == NULL) { SwooleG.serv->onClose = php_swoole_onClose; } break; } } if (l_property_name == 0) { swoole_php_error(E_WARNING, "Unknown event types[%s]", name); RETURN_FALSE; } RETURN_TRUE; }
static PHP_METHOD(swoole_process, signal) { zval *callback = NULL; long signo = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &signo, &callback) == FAILURE) { return; } if (!SWOOLE_G(cli)) { swoole_php_fatal_error(E_ERROR, "cannot use swoole_process::signal here."); RETURN_FALSE; } if (SwooleGS->start && (swIsWorker() || swIsMaster() || swIsManager() || swIsTaskWorker())) { if (signo == SIGTERM || signo == SIGALRM) { swoole_php_fatal_error(E_WARNING, "cannot use swoole_process::signal in swoole_server."); RETURN_FALSE; } } if (callback == NULL || ZVAL_IS_NULL(callback)) { callback = signal_callback[signo]; if (callback) { sw_zval_ptr_dtor(&callback); swSignal_add(signo, NULL); RETURN_TRUE; } else { swoole_php_error(E_WARNING, "no callback."); RETURN_FALSE; } } char *func_name; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { swoole_php_error(E_WARNING, "function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); #if PHP_MAJOR_VERSION >= 7 zval *tmp = emalloc(sizeof(zval)); memcpy(tmp, callback, sizeof(zval)); callback = tmp; #endif sw_zval_add_ref(&callback); if (signal_callback[signo]) { sw_zval_ptr_dtor(&callback); } signal_callback[signo] = callback; #if PHP_MAJOR_VERSION >= 7 || (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4) SwooleG.use_signalfd = 1; #else SwooleG.use_signalfd = 0; #endif php_swoole_check_reactor(); /** * for swSignalfd_setup */ SwooleG.main_reactor->check_signalfd = 1; swSignal_add(signo, php_swoole_onSignal); RETURN_TRUE; }