static void ngx_http_push_channel_handler(ngx_event_t *ev) { //copypasta from os/unix/ngx_process_cycle.c (ngx_channel_handler) ngx_int_t n; ngx_channel_t ch; ngx_connection_t *c; if (ev->timedout) { ev->timedout = 0; return; } c = ev->data; while(1) { n = ngx_read_channel(c->fd, &ch, sizeof(ch), ev->log); if (n == NGX_ERROR) { if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { ngx_del_conn(c, 0); } ngx_close_connection(c); return; } if ((ngx_event_flags & NGX_USE_EVENTPORT_EVENT) && (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR)) { return; } if (n == NGX_AGAIN) { return; } //ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "push module: channel command: %d", ch.command); if (ch.command==NGX_CMD_HTTP_PUSH_CHECK_MESSAGES) { ngx_http_push_store->receive_worker_message(); } } }
static void ngx_http_push_stream_channel_handler(ngx_event_t *ev) { // copypaste from os/unix/ngx_process_cycle.c (ngx_channel_handler) ngx_int_t n; ngx_channel_t ch; ngx_connection_t *c; if (ev->timedout) { ev->timedout = 0; return; } c = ev->data; while (1) { n = ngx_read_channel(c->fd, &ch, sizeof(ch), ev->log); if (n == NGX_ERROR) { if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { ngx_del_conn(c, 0); } ngx_close_connection(c); return; } if ((ngx_event_flags & NGX_USE_EVENTPORT_EVENT) && (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR)) { return; } if (n == NGX_AGAIN) { return; } if (ch.command == NGX_CMD_HTTP_PUSH_STREAM_CHECK_MESSAGES.command) { ngx_http_push_stream_process_worker_message(); } else if (ch.command == NGX_CMD_HTTP_PUSH_STREAM_CENSUS_SUBSCRIBERS.command) { ngx_http_push_stream_census_worker_subscribers(); } else if (ch.command == NGX_CMD_HTTP_PUSH_STREAM_DELETE_CHANNEL.command) { ngx_http_push_stream_delete_worker_channel(); } } }
static void ngx_channel_handler(ngx_event_t *ev) { ngx_int_t n; ngx_channel_t ch; ngx_connection_t *c; if (ev->timedout) { ev->timedout = 0; return; } c = ev->data; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler"); for ( ;; ) { n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log); ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n); if (n == NGX_ERROR) { if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { ngx_del_conn(c, 0); } ngx_close_connection(c); return; } if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) { if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) { return; } } if (n == NGX_AGAIN) { return; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel command: %d", ch.command); switch (ch.command) { case NGX_CMD_QUIT: ngx_quit = 1; break; case NGX_CMD_TERMINATE: ngx_terminate = 1; break; case NGX_CMD_REOPEN: ngx_reopen = 1; break; case NGX_CMD_OPEN_CHANNEL: ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0, "get channel s:%i pid:%P fd:%d", ch.slot, ch.pid, ch.fd); ngx_processes[ch.slot].pid = ch.pid; ngx_processes[ch.slot].channel[0] = ch.fd; break; case NGX_CMD_CLOSE_CHANNEL: ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0, "close channel s:%i pid:%P our:%P fd:%d", ch.slot, ch.pid, ngx_processes[ch.slot].pid, ngx_processes[ch.slot].channel[0]); if (close(ngx_processes[ch.slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() channel failed"); } ngx_processes[ch.slot].channel[0] = -1; break; } } }
/* 子进程收到后来新建子进程的相关信息,并根据通道的命令完成相应的动作 */ static void ngx_channel_handler(ngx_event_t *ev) { ngx_int_t n; ngx_channel_t ch; ngx_connection_t *c; if (ev->timedout) { ev->timedout = 0; return; } c = ev->data; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler"); for ( ;; ) { /* 从连接中的socket文件描述符中读取通道数据 */ n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log); ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n); if (n == NGX_ERROR) { if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { ngx_del_conn(c, 0); } ngx_close_connection(c); return; } if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) { if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) { return; } } if (n == NGX_AGAIN) { return; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel command: %d", ch.command); switch (ch.command) { case NGX_CMD_QUIT: ngx_quit = 1; /* 如果worker进程通过通道接收到退出命令,则设置全局变量ngx_quit为1 */ break; case NGX_CMD_TERMINATE: ngx_terminate = 1; break; case NGX_CMD_REOPEN: ngx_reopen = 1; break; /* 子进程之间的通信打开通道,如master进程将后续创建的子进程的 * pid,fd,以及slot发送过来,高速之前创建的进程怎么和后续创建的进程通信 */ case NGX_CMD_OPEN_CHANNEL: ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0, "get channel s:%i pid:%P fd:%d", ch.slot, ch.pid, ch.fd); ngx_processes[ch.slot].pid = ch.pid; /* 设置进程的0通道,在刚创建的时候,子进程的0通道是从父进程继承的 */ ngx_processes[ch.slot].channel[0] = ch.fd; break; case NGX_CMD_CLOSE_CHANNEL: /* 关闭与相应进程(也就是索引为ch.slot的这个进程的通信信道 */ ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0, "close channel s:%i pid:%P our:%P fd:%d", ch.slot, ch.pid, ngx_processes[ch.slot].pid, ngx_processes[ch.slot].channel[0]); if (close(ngx_processes[ch.slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() channel failed"); } ngx_processes[ch.slot].channel[0] = -1; break; } } }
static void ngx_channel_handler(ngx_event_t *ev) { ngx_int_t n; ngx_channel_t ch; ngx_connection_t *c; c = ev->data; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler"); n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log); ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %d", n); if (n <= 0) { return; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel command: %d", ch.command); switch (ch.command) { case NGX_CMD_QUIT: ngx_quit = 1; break; case NGX_CMD_TERMINATE: ngx_terminate = 1; break; case NGX_CMD_REOPEN: ngx_reopen = 1; break; case NGX_CMD_OPEN_CHANNEL: ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0, "get channel s:%d pid:" PID_T_FMT " fd:%d", ch.slot, ch.pid, ch.fd); ngx_processes[ch.slot].pid = ch.pid; ngx_processes[ch.slot].channel[0] = ch.fd; break; case NGX_CMD_CLOSE_CHANNEL: ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0, "close channel s:%d pid:" PID_T_FMT " our:" PID_T_FMT " fd:%d", ch.slot, ch.pid, ngx_processes[ch.slot].pid, ngx_processes[ch.slot].channel[0]); if (close(ngx_processes[ch.slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() failed"); } ngx_processes[ch.slot].channel[0] = -1; break; } }