/* This function adds all of the protocol's listener's file descriptors to the * polling lists when they are in the LI_LISTEN state. It is intended to be * used as a protocol's generic enable_all() primitive, for use after the * fork(). It puts the listeners into LI_READY or LI_FULL states depending on * their number of connections. It always returns ERR_NONE. */ int enable_all_listeners(struct protocol *proto) { struct listener *listener; list_for_each_entry(listener, &proto->listeners, proto_list) enable_listener(listener); return ERR_NONE; }
/* * this function enables proxies when there are enough free sessions, * or stops them when the table is full. It is designed to be called from the * select_loop(). It adjusts the date of next expiration event during stop * time if appropriate. */ void maintain_proxies(int *next) { struct proxy *p; struct listener *l; unsigned int wait; p = proxy; /* if there are enough free sessions, we'll activate proxies */ if (actconn < global.maxconn) { for (; p; p = p->next) { /* check the various reasons we may find to block the frontend */ if (p->feconn >= p->maxconn) goto do_block; if (p->fe_sps_lim && (wait = next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 1))) { /* we're blocking because a limit was reached on the number of * requests/s on the frontend. We want to re-check ASAP, which * means in 1 ms before estimated expiration date, because the * timer will have settled down. Note that we may already be in * IDLE state here. */ *next = tick_first(*next, tick_add(now_ms, wait)); goto do_block; } /* OK we have no reason to block, so let's unblock if we were blocking */ if (p->state == PR_STIDLE) { for (l = p->listen; l != NULL; l = l->next) enable_listener(l); p->state = PR_STRUN; } continue; do_block: if (p->state == PR_STRUN) { for (l = p->listen; l != NULL; l = l->next) disable_listener(l); p->state = PR_STIDLE; } } } else { /* block all proxies */ while (p) { if (p->state == PR_STRUN) { for (l = p->listen; l != NULL; l = l->next) disable_listener(l); p->state = PR_STIDLE; } p = p->next; } } if (stopping) { p = proxy; while (p) { if (p->state != PR_STSTOPPED) { int t; t = tick_remain(now_ms, p->stop_time); if (t == 0) { Warning("Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n", p->id, p->cum_feconn, p->cum_beconn); send_log(p, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n", p->id, p->cum_feconn, p->cum_beconn); stop_proxy(p); /* try to free more memory */ pool_gc2(); } else { *next = tick_first(*next, p->stop_time); } } p = p->next; } } return; }