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 )