📄 srun_conn.c
字号:
*/static voidbrowser_busy(browser_t *browser){ char buf[128]; if (! browser) return; LOG(("sending busy message %s", browser_state_name(browser))); browser->next_state = browser->state; browser->state = RHC_BROWSER_WRITE; format_now(buf); browser_printf(browser, "HTTP/1.0 503 Server Busy\r\n"); browser_printf(browser, "Connection: close\r\n"); browser_printf(browser, "Date: %s\r\n", buf); browser_printf(browser, "Server: Resin-HardCore\r\n"); browser_printf(browser, "\r\n"); browser_printf(browser, "<title>Server Busy</title>\n"); browser_printf(browser, "<h1>503 Server Busy</h1>\n"); browser_printf(browser, "The server is busy or currently unavailable.\n"); browser_printf(browser, "Please try again later.\n"); browser_printf(browser, "<hr>\n"); browser_printf(browser, "<em>Resin-Hardcore/2.0</em>\n");}/** * Write data to the srun * * @param sock the kernel's socket object * @param buf the buffer to write * @param len the amount of data to write * * @return the number of bytes written or < 0 on error. */static intsocket_send(struct sock *sock, char *buf, int len){ mm_segment_t oldfs; struct msghdr msg; struct iovec iov; if (! sock) return -1; if (len <= 0) return -1; msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL; iov.iov_base = buf; iov.iov_len = len; LOG(("sending %p %p %d %p\n", sock, buf, len, sock->prot ? (char *) sock->prot->sendmsg : (char *) sock->prot)); // This bit of vm magic is needed to avoid freezing the kernel oldfs = get_fs(); set_fs(KERNEL_DS); len = sock->prot->sendmsg(sock, &msg, len); set_fs(oldfs); LOG(("post send %d\n", len)); return len;}/** * Write data to the srun * * @param browser The browser connection */voidsrun_send(browser_t *browser){ struct socket *sock = browser->srun_sock; int offset = browser->sout_offset; int len = browser->sout_length; char *buf = browser->sout_buf + offset; if (! sock) return; if (offset >= len) { browser->state = browser->next_state; return; } len = socket_send(sock->sk, buf, len - offset); if (len < 0) LOG(("send error %d\n", len)); // XXX: no space is possible else { LOG(("srun sent %d\n", len)); browser->sout_offset += len; if (browser->sout_offset >= browser->sout_length) browser->state = browser->next_state; }}/** * Reads from the client socket into the srun in buffer (sin_*) * * @param browser The browser connection * * @return number of bytes read */intsrun_recv(browser_t *browser){ int len; if (browser->sin_offset >= browser->sin_length) { browser->sin_offset = 0; browser->sin_length = 0; } len = sizeof(browser->sin_buf) - browser->sin_length; if (len < 0) return len; LOG(("recv off:%d len:%d\n", browser->sin_offset, browser->sin_length)); len = socket_recv(browser->srun_sock->sk, browser->sin_buf + browser->sin_length, len); if (len > 0) browser->sin_length += len; return len;}/** * Recycles the srun structure so another connection can reuse it. */voidsrun_recycle(srun_conn_t *srun_conn){ srun_t *srun = srun_conn->parent; if (! srun->is_live) { srun_start_close(srun_conn); return; } srun_conn->browser = 0; srun_conn->next = srun->conn_head; srun_conn->prev = 0; if (srun->conn_head) srun->conn_head->prev = srun_conn; srun->conn_head = srun_conn; LOG(("recycle srun:%p\n", srun));}/** * Closes the srun connection. * * @param srun_conn the srun connection */static voidsrun_conn_close(srun_conn_t *srun_conn){ browser_t *browser; struct socket *socket; if (! srun_conn) return; browser = srun_conn->browser; srun_conn->browser = 0; socket = srun_conn->sock; srun_conn->sock = 0; if (browser) { LOG(("browser close\n")); browser->srun_conn = 0; browser_close(browser); } if (socket && socket->sk) { socket->sk->user_data = 0; // need to restore the default values socket->sk->state_change = srun_conn->old_state_change; socket->sk->data_ready = srun_conn->old_data_ready; } if (socket) { LOG(("close socket\n")); sock_release(socket); } kfree(srun_conn);}/** * Cleans up any sruns awaiting close. Always called from the resind thread. */voidsrun_execute(resin_t *resin){ LOG(("executing srun\n")); while (g_srun_close_list) { srun_conn_t *srun_conn; spin_lock_irq(&g_srun_lock); srun_conn = g_srun_close_list; if (srun_conn) g_srun_close_list = srun_conn->next; spin_unlock_irq(&g_srun_lock); LOG(("closing %p\n", srun_conn)); srun_conn_close(srun_conn); }}/** * Adds a new srun on initialization. */voidsrun_create(resin_t *resin, int index, int ipv4, int port){ srun_t *srun; // XXX: lock srun = &resin->srun_list[index]; if (srun->is_live) return; LOG(("init: index:%d ip:%p port:%d\n", index, ipv4, port)); if (index >= resin->srun_count) srun_set_count(resin, index + 1); srun->resin = resin; srun->addr.s_addr = htonl(ipv4); srun->port = port; srun->is_backup = 0; srun->session_index = index; srun->conn_head = 0; srun->is_live = 1;}/** * Initialize the srun */voidsrun_init(resin_t *resin){ srun_create(resin, 0, IP(127, 0, 0, 1), 6802);}/** * Closes the srun on shutdown */voidsrun_close(srun_t *srun){ spin_lock_irq(&g_srun_lock); if (! srun || ! srun->is_live) { spin_unlock_irq(&g_srun_lock); return; } srun->is_live = 0; while (srun->conn_head) srun_start_close(srun->conn_head); spin_unlock_irq(&g_srun_lock);}/** * Sets the maximum number of sruns */voidsrun_set_count(resin_t *resin, int count){ int i; for (i = count; i < resin->srun_count; i++) srun_close(&resin->srun_list[i]); for (i = resin->srun_count; i < count; i++) { resin->srun_list[i].resin = resin; resin->srun_list[i].is_live = 0; } resin->srun_count = count;}/** * Cleans up all sruns awaiting close. Called only from resind */voidsrun_cleanup(resin_t *resin){ int i; LOG(("closing srun\n")); for (i = 0; i < resin->srun_count; i++) srun_close(&resin->srun_list[i]); srun_execute(resin); LOG(("closed srun\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -