--- libaitio/src/exec.c 2013/12/05 12:43:04 1.1 +++ libaitio/src/exec.c 2013/12/05 12:43:04 1.1.2.1 @@ -0,0 +1,169 @@ +#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); + 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; +}