in native/common/jk_ajp_common.c [3510:3636]
int JK_METHOD ajp_maintain(jk_worker_t *pThis, time_t mstarted, int global,
jk_log_context_t *l)
{
JK_TRACE_ENTER(l);
if (pThis && pThis->worker_private) {
ajp_worker_t *aw = pThis->worker_private;
int i;
unsigned int n = 0, k = 0, cnt = 0;
unsigned int m, m_count = 0;
jk_sock_t *m_sock;
/* Do connection pool maintenance only if timeouts or keepalives are set
*/
if (aw->cache_timeout <= 0 &&
aw->conn_ping_interval <= 0) {
/* Nothing to do.
*/
JK_TRACE_EXIT(l);
return JK_TRUE;
}
JK_ENTER_CS(&aw->cs);
/* Count open slots
*/
for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) {
if (aw->ep_cache[i] && IS_VALID_SOCKET(aw->ep_cache[i]->sd))
cnt++;
}
m_sock = (jk_sock_t *)malloc((cnt + 1) * sizeof(jk_sock_t));
/* Handle worker cache timeouts
*/
if (aw->cache_timeout > 0) {
for (i = (int)aw->ep_cache_sz - 1;
i >= 0; i--) {
/* Skip the closed sockets
*/
if (IS_SLOT_AVAIL(aw->ep_cache[i]) &&
IS_VALID_SOCKET(aw->ep_cache[i]->sd)) {
int elapsed = (int)difftime(mstarted,
aw->ep_cache[i]->last_access);
if (elapsed > aw->cache_timeout) {
time_t rt = 0;
n++;
if (JK_IS_DEBUG_LEVEL(l))
rt = time(NULL);
aw->ep_cache[i]->reuse = JK_FALSE;
m_sock[m_count++] = aw->ep_cache[i]->sd;
aw->ep_cache[i]->sd = JK_INVALID_SOCKET;
ajp_reset_endpoint(aw->ep_cache[i], l);
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"(%s) cleaning pool slot=%d elapsed %d in %d",
aw->name, i, elapsed,
(int)(difftime(time(NULL), rt)));
}
}
if (cnt <= aw->ep_mincache_sz + n) {
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"(%s) reached pool min size %u from %u cache slots",
aw->name, aw->ep_mincache_sz, aw->ep_cache_sz);
}
break;
}
}
}
/* Handle worker connection keepalive
*/
if (aw->conn_ping_interval > 0 && aw->ping_timeout > 0) {
for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) {
/* Skip the closed sockets
*/
if (IS_SLOT_AVAIL(aw->ep_cache[i]) &&
IS_VALID_SOCKET(aw->ep_cache[i]->sd)) {
int elapsed = (int)difftime(mstarted,
aw->ep_cache[i]->last_access);
if (elapsed > aw->conn_ping_interval) {
k++;
/* handle cping/cpong.
*/
if (ajp_handle_cping_cpong(aw->ep_cache[i],
aw->ping_timeout, l) == JK_FALSE) {
jk_log(l, JK_LOG_INFO,
"(%s) failed sending request, "
"socket %d keepalive cping/cpong "
"failure (errno=%d)",
aw->name,
aw->ep_cache[i]->sd,
aw->ep_cache[i]->last_errno);
aw->ep_cache[i]->reuse = JK_FALSE;
m_sock[m_count++] = aw->ep_cache[i]->sd;
aw->ep_cache[i]->sd = JK_INVALID_SOCKET;
ajp_reset_endpoint(aw->ep_cache[i], l);
}
}
}
}
}
JK_LEAVE_CS(&aw->cs);
/* Shutdown sockets outside of the lock.
* This has benefits only if maintain was
* called from the watchdog thread.
*/
for (m = 0; m < m_count; m++) {
if (IS_VALID_SOCKET(m_sock[m])) {
jk_shutdown_socket(m_sock[m], l);
JK_ATOMIC_DECREMENT(&(aw->s->connected));
}
}
free(m_sock);
if ((k + n) && JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"(%s) pinged %u and recycled %u sockets in %d seconds "
"from %u pool slots",
aw->name, k, n, (int)(difftime(time(NULL), mstarted)),
aw->ep_cache_sz);
JK_TRACE_EXIT(l);
return JK_TRUE;
}
else {
JK_LOG_NULL_PARAMS(l);
}
JK_TRACE_EXIT(l);
return JK_FALSE;
}