struct freq_ctr conn_per_sec; /* connections per second */
struct freq_ctr err_per_sec; /* connection errors per second */
+ unsigned int idles; /* # of idle applets */
struct eb_root idle_applets; /* idle SPOE applets available to process data */
struct list applets; /* all SPOE applets for this agent */
struct list sending_queue; /* Queue of streams waiting to send data */
if (appctx->st0 == SPOE_APPCTX_ST_IDLE) {
eb32_delete(&spoe_appctx->node);
_HA_ATOMIC_DEC(&agent->counters.idles);
+ agent->rt[tid].idles--;
}
appctx->st0 = SPOE_APPCTX_ST_END;
default:
_HA_ATOMIC_INC(&agent->counters.idles);
+ agent->rt[tid].idles++;
appctx->st0 = SPOE_APPCTX_ST_IDLE;
SPOE_APPCTX(appctx)->node.key = 0;
eb32_insert(&agent->rt[tid].idle_applets, &SPOE_APPCTX(appctx)->node);
goto next;
}
_HA_ATOMIC_INC(&agent->counters.idles);
+ agent->rt[tid].idles++;
appctx->st0 = SPOE_APPCTX_ST_IDLE;
eb32_insert(&agent->rt[tid].idle_applets, &SPOE_APPCTX(appctx)->node);
}
case SPOE_APPCTX_ST_IDLE:
_HA_ATOMIC_DEC(&agent->counters.idles);
+ agent->rt[tid].idles--;
eb32_delete(&SPOE_APPCTX(appctx)->node);
if (stopping &&
LIST_ISEMPTY(&agent->rt[tid].sending_queue) &&
struct spoe_appctx *spoe_appctx;
/* Check if we need to create a new SPOE applet or not. */
- if (!eb_is_empty(&agent->rt[tid].idle_applets) &&
- (agent->rt[tid].processing == 1 || agent->rt[tid].processing < read_freq_ctr(&agent->rt[tid].processing_per_sec)))
+ if (agent->rt[tid].processing < agent->rt[tid].idles ||
+ agent->rt[tid].processing < read_freq_ctr(&agent->rt[tid].processing_per_sec))
goto end;
SPOE_PRINTF(stderr, "%d.%06d [SPOE/%-15s] %s: stream=%p"
conf->agent->rt[i].engine_id = NULL;
conf->agent->rt[i].frame_size = conf->agent->max_frame_size;
conf->agent->rt[i].processing = 0;
+ conf->agent->rt[i].idles = 0;
LIST_INIT(&conf->agent->rt[i].applets);
LIST_INIT(&conf->agent->rt[i].sending_queue);
LIST_INIT(&conf->agent->rt[i].waiting_queue);