CGI-SpeedyCGI
view release on metacpan or search on metacpan
src/speedy_frontend.c view on Meta::CPAN
speedy_util_exit(0,1);
}
else {
/* Grandchild */
/* We should be in our own session */
setsid();
/* Exec the backend */
speedy_util_execvp(argv[0], argv);
/* Failed. Try the original argv[0] + "_backend" */
{
const char *orig_file = speedy_opt_orig_argv()[0];
if (orig_file && *orig_file) {
char *fname;
speedy_new(
fname, strlen(orig_file)+sizeof(BE_SUFFIX)+1, char
);
sprintf(fname, "%s%s", orig_file, BE_SUFFIX);
speedy_util_execvp(fname, argv);
}
}
speedy_util_die(argv[0]);
}
} else {
speedy_util_die("fork");
}
}
/* Check on / spawn backends. Should only be done by the fe at the
* head of the list (think 100+ fe's in the queue)
*/
static int backend_check(slotnum_t gslotnum, int *did_spawn) {
gr_slot_t *gslot = &FILE_SLOT(gr_slot, gslotnum);
/* Don't spawn a backend while a backend is starting */
if (speedy_group_be_starting(gslotnum))
return 1;
/* If we already did this once, it didn't work */
if (*did_spawn)
return 0;
/* Start up a be_parent if necessary */
if (!gslot->be_parent)
be_parent_spawn(gslotnum);
/* Are we below the maxbackends limit? */
if (speedy_backend_below_maxbe(gslotnum)) {
/* Signal the be parent to start a new backend */
if (speedy_group_start_be(gslotnum)) {
/* Let it start one before spawning again */
gslot->be_starting = gslot->be_parent;
*did_spawn = 1;
}
} else {
/* If we're above the maxbaceknds limit, we still need to ping the
* be parent to make sure it's alive.
*/
speedy_group_parent_sig(gslotnum, 0);
}
return 1;
}
/* Go up the fe list, going to the next group if we're at the
* begininng of the list. Wrap to the first group if we go off the end
* of the group list. Worst case we wrap around and return ourself.
*/
static void fe_prev(slotnum_t *gslotnum, slotnum_t *fslotnum) {
*fslotnum = speedy_slot_prev(*fslotnum);
while (!*fslotnum) {
if (!(*gslotnum = speedy_slot_next(*gslotnum)) &&
!(*gslotnum = FILE_HEAD.group_head))
{
DIE_QUIET("Group list or frontend lists are corrupt");
}
*fslotnum = FILE_SLOT(gr_slot, *gslotnum).fe_tail;
}
}
static void frontend_check_prev(slotnum_t gslotnum, slotnum_t fslotnum) {
fe_prev(&gslotnum, &fslotnum);
while (speedy_frontend_dead(fslotnum)) {
slotnum_t g_prev = gslotnum, f_prev = fslotnum;
/* Must do "prev" function while this slot/group is still valid */
fe_prev(&g_prev, &f_prev);
/* This frontend is not running so dispose of it */
speedy_frontend_dispose(gslotnum, fslotnum);
/* Try to remove this group if possible */
speedy_group_cleanup(gslotnum);
/* If we wrapped around to ourself, then all done */
if (f_prev == fslotnum)
break;
gslotnum = g_prev;
fslotnum = f_prev;
}
}
/* Check that the frontend in front of is running. Also run backend check
* if we are the head frontend
*/
static int frontend_ping
(slotnum_t gslotnum, slotnum_t fslotnum, int *did_spawn)
{
/* Check the frontend previous to us. This may remove it */
frontend_check_prev(gslotnum, fslotnum);
/* If we're not the head of the list, then all done */
if (speedy_slot_prev(fslotnum))
return 1;
/* Do a check of backends. Returns false if we cannot start be */
( run in 0.700 second using v1.01-cache-2.11-cpan-df04353d9ac )