File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / exec.c
Revision 1.1.2.2: download - view: text, annotated - select for diffs - revision graph
Thu Dec 5 12:57:35 2013 UTC (10 years, 6 months ago) by misho
Branches: io6_7
init prog

#include "global.h"


/*
 * io_progInit() - Init program pool
 *
 * @progName = program name for execution
 * @initNum = initial started programs
 * @maxNum = maximum started programs
 * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy())
 */
prog_t *
io_progInit(const char *progName, u_int initNum, u_int maxNum)
{
	prog_t *prg = NULL;

	if (initNum > maxNum)
		return NULL;

	prg = e_malloc(sizeof(prog_t));
	if (!prg) {
		io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
		return NULL;
	} else
		memset(prg, 0, sizeof(prog_t));

	prg->prog_inin = initNum;
	prg->prog_maxn = maxNum;
	strlcpy(prg->prog_name, progName, sizeof prg->prog_name);

	prg->prog_fds = array_Init(prg->prog_maxn);
	if (!prg->prog_fds) {
		io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
		e_free(prg);
		return NULL;
	}

	pthread_mutex_init(&prg->prog_mtx, NULL);

	if (!io_progOpen(prg, prg->prog_inin))
		io_progDestroy(&prg);
	return prg;
}

/*
 * io_progDestroy() - Destroy entire program pool
 *
 * @pprg = program pool
 * return: none
 */
void
io_progDestroy(prog_t ** __restrict pprg)
{
	if (!pprg || !*pprg)
		return;

	io_progClose(*pprg, 0);

	array_Destroy(&(*pprg)->prog_fds);
	pthread_mutex_destroy(&(*pprg)->prog_mtx);

	e_free(*pprg);
	*pprg = NULL;
}

/*
 * io_progClose() - Close all programs in pool
 *
 * @prg = program pool
 * @closeNum = close program(s) (0 all)
 * return: 0 error, >0 closed programs
 */
int
io_progClose(prog_t * __restrict prg, u_int closeNum)
{
	register int i;
	int ret = 0;

	if (!prg)
		return 0;
	if (closeNum > prg->prog_maxn) {
		io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
		return 0;
	}

	pthread_mutex_lock(&prg->prog_mtx);
	for (i = array_Size(prg->prog_fds) - 1; 
			(closeNum ? ret < closeNum : 42) && i > -1; i--)
		if (array_Get(prg->prog_fds, i)) {
			pclose(array(prg->prog_fds, i, FILE*));
			array_Del(prg->prog_fds, i, 0);
			prg->prog_cnum--;
			ret++;
		}
	pthread_mutex_unlock(&prg->prog_mtx);

	return ret;
}

/*
 * io_progOpen() - Execute number of program(s)
 *
 * @prg = program pool
 * @execNum = execute program(s) (0 max)
 * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
 */
int
io_progOpen(prog_t * __restrict prg, u_int execNum)
{
	FILE *f;
	int ret = 0;
	register int i;

	if (!prg)
		return 0;
	if (execNum > prg->prog_maxn) {
		io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
		return 0;
	}

	pthread_mutex_lock(&prg->prog_mtx);
	for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
		if (!array_Get(prg->prog_fds, i)) {
			f = popen(prg->prog_name, "r+");
			if (!f) {
				LOGERR;
				ret *= -1;
				break;
			} else
				array_Set(prg->prog_fds, i, f);
			prg->prog_cnum++;
			ret++;
		}
	pthread_mutex_unlock(&prg->prog_mtx);

	return ret;
}

/*
 * io_progVacuum() - Vacuum pool to running number of programs
 *
 * @prg = program pool
 * @toNum = vacuum to number of programs (0 to init number)
 * return: 0 error or >0 closed programs
 */
int
io_progVacuum(prog_t * __restrict prg, u_int toNum)
{
	register int i;
	int ret = 0;

	if (!prg)
		return 0;
	if (toNum > prg->prog_maxn) {
		io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
		return 0;
	}
	if (!toNum)
		toNum = prg->prog_inin;

	pthread_mutex_lock(&prg->prog_mtx);
	for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
		if (array_Get(prg->prog_fds, i)) {
			pclose(array(prg->prog_fds, i, FILE*));
			array_Del(prg->prog_fds, i, 0);
			prg->prog_cnum--;
			ret++;
		}
	pthread_mutex_unlock(&prg->prog_mtx);

	return ret;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>