PersistentPerl

 view release on metacpan or  search on metacpan

src/perperl_frontend.c  view on Meta::CPAN

static void frontend_check_prev(slotnum_t gslotnum, slotnum_t fslotnum) {
    fe_prev(&gslotnum, &fslotnum);

    while (perperl_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 */
	perperl_frontend_dispose(gslotnum, fslotnum);

	/* Try to remove this group if possible */
	perperl_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 (perperl_slot_prev(fslotnum))
	return 1;

    /* Do a check of backends.  Returns false if we cannot start be */
    return backend_check(gslotnum, did_spawn);
}


/* Get a backend the hard-way - by queueing up
*/
static int get_a_backend_hard
    (slotnum_t gslotnum, slotnum_t fslotnum, slotnum_t *bslotnum)
{
    int file_changed, did_spawn = 0, spawn_working = 1, sent_sig;
    *bslotnum = 0;

    /* Install sig handlers */
    sig_handler_setup();

    /* Put ourself at the end of the fe queue */
    perperl_slot_append(fslotnum,
	&(FILE_SLOT(gr_slot, gslotnum).fe_head),
	&(FILE_SLOT(gr_slot, gslotnum).fe_tail));

    while (1) {
	/* Send signals to frontends */
	perperl_group_sendsigs(gslotnum);

	sent_sig = FILE_SLOT(fe_slot, fslotnum).sent_sig;
	FILE_SLOT(fe_slot, fslotnum).sent_sig = 0;

	/* If our sent_sig flag is set, and there are be's for us to use ,
	 * then all done.
	*/
	if (sent_sig &&
	    (*bslotnum = perperl_backend_be_wait_get(gslotnum)))
	{
	    break;
	}

	/* Check on frontends/backends running */
	spawn_working = frontend_ping(gslotnum, fslotnum, &did_spawn);

	/* Frontend ping may have invalidated our group */
	if (!spawn_working || !perperl_group_isvalid(gslotnum))
	    break;

	/* Unlock the file */
	perperl_file_set_state(FS_HAVESLOTS);

	/* Set an alarm for one-second or so. */
	alarm(OPTVAL_BECHECKTIMEOUT);

	/* Wait for a timeout or signal from backend */
	perperl_sig_wait(&sl);

	/* Find out if our file changed.  Do this while unlocked */
	file_changed = perperl_script_changed();

	/* Acquire lock.  If group bad or file changed, then done */
	if (!perperl_group_lock(gslotnum) || file_changed)
	    break;
    }

    /* Remove our FE slot from the queue.  */
    perperl_slot_remove(fslotnum,
	&(FILE_SLOT(gr_slot, gslotnum).fe_head),
	&(FILE_SLOT(gr_slot, gslotnum).fe_tail));

    /* Put sighandlers back to their original state */
    sig_handler_teardown(1);

    return spawn_working;
}

static int get_a_backend(slotnum_t fslotnum, slotnum_t *gslotnum) {
    slotnum_t bslotnum = 0;
    int spawn_working = 1;

    /* Locate the group for our script */
    *gslotnum = perperl_script_find();

    /* Try to quickly grab a backend without queueing */
    if (!FILE_SLOT(gr_slot, *gslotnum).fe_head)
	bslotnum = perperl_backend_be_wait_get(*gslotnum);

    /* If that failed, use the queue */



( run in 1.474 second using v1.01-cache-2.11-cpan-71847e10f99 )