/* * pool_main_loop * Accept new connections from clients, and handle all input from clients and * pool members. */ static void pool_main_loop(TDS_POOL * pool) { TDS_POOL_MEMBER *pmbr; TDS_POOL_USER *puser; TDS_SYS_SOCKET s, wakeup; SELECT_INFO sel; s = pool->listen_fd; wakeup = pool->wakeup_fd; while (!got_sigterm) { FD_ZERO(&sel.rfds); FD_ZERO(&sel.wfds); /* add the listening socket to the read list */ FD_SET(s, &sel.rfds); FD_SET(wakeup, &sel.rfds); sel.maxfd = s > wakeup ? s : wakeup; /* add the user sockets to the read list */ DLIST_FOREACH(dlist_user, &pool->users, puser) pool_select_add_socket(&sel, &puser->sock); /* add the pool member sockets to the read list */ DLIST_FOREACH(dlist_member, &pool->active_members, pmbr) pool_select_add_socket(&sel, &pmbr->sock); /* FIXME check return value */ select(sel.maxfd + 1, &sel.rfds, &sel.wfds, NULL, NULL); if (TDS_UNLIKELY(got_sigterm)) break; if (TDS_UNLIKELY(got_sighup)) { got_sighup = 0; pool_open_logfile(pool); } /* process events */ if (FD_ISSET(wakeup, &sel.rfds)) { char buf[32]; READSOCKET(wakeup, buf, sizeof(buf)); pool_process_events(pool); } /* process the sockets */ if (FD_ISSET(s, &sel.rfds)) { pool_user_create(pool, s); } pool_process_users(pool, &sel.rfds, &sel.wfds); pool_process_members(pool, &sel.rfds, &sel.wfds); /* back from members */ if (dlist_user_first(&pool->waiters)) pool_schedule_waiters(pool); } /* while !got_sigterm */ tdsdump_log(TDS_DBG_INFO2, "Shutdown Requested\n"); }
/* * pool_main_loop * Accept new connections from clients, and handle all input from clients and * pool members. */ static void pool_main_loop(TDS_POOL * pool) { TDS_POOL_USER *puser; TDS_POOL_MEMBER *pmbr; struct sockaddr_in sin; int s, maxfd, i; fd_set rfds; int socktrue = 1; /* FIXME -- read the interfaces file and bind accordingly */ sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(pool->port); sin.sin_family = AF_INET; if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) { perror("socket"); exit(1); } /* don't keep addr in use from [email protected] */ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const void *) &socktrue, sizeof(socktrue)); fprintf(stderr, "Listening on port %d\n", pool->port); if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } listen(s, 5); FD_ZERO(&rfds); FD_SET(s, &rfds); maxfd = s; while (!term) { /* fprintf(stderr, "waiting for a connect\n"); */ /* FIXME check return value */ select(maxfd + 1, &rfds, NULL, NULL, NULL); if (term) break; /* process the sockets */ if (FD_ISSET(s, &rfds)) { pool_user_create(pool, s, &sin); } pool_process_users(pool, &rfds); pool_process_members(pool, &rfds); /* back from members */ if (waiters) { pool_schedule_waiters(pool); } FD_ZERO(&rfds); /* add the listening socket to the read list */ FD_SET(s, &rfds); maxfd = s; /* add the user sockets to the read list */ for (i = 0; i < pool->max_users; i++) { puser = (TDS_POOL_USER *) & pool->users[i]; /* skip dead connections */ if (!IS_TDSDEAD(puser->tds)) { if (tds_get_s(puser->tds) > maxfd) maxfd = tds_get_s(puser->tds); FD_SET(tds_get_s(puser->tds), &rfds); } } /* add the pool member sockets to the read list */ for (i = 0; i < pool->num_members; i++) { pmbr = (TDS_POOL_MEMBER *) & pool->members[i]; if (!IS_TDSDEAD(pmbr->tds)) { if (tds_get_s(pmbr->tds) > maxfd) maxfd = tds_get_s(pmbr->tds); FD_SET(tds_get_s(pmbr->tds), &rfds); } } } /* while !term */ CLOSESOCKET(s); for (i = 0; i < pool->max_users; i++) { puser = (TDS_POOL_USER *) & pool->users[i]; if (!IS_TDSDEAD(puser->tds)) { fprintf(stderr, "Closing user %d\n", i); tds_close_socket(puser->tds); } } for (i = 0; i < pool->num_members; i++) { pmbr = (TDS_POOL_MEMBER *) & pool->members[i]; if (!IS_TDSDEAD(pmbr->tds)) { fprintf(stderr, "Closing member %d\n", i); tds_close_socket(pmbr->tds); } } }