--- libaitio/src/exec.c 2013/12/05 15:18:22 1.1.2.6 +++ libaitio/src/exec.c 2013/12/06 01:03:05 1.1.2.11 @@ -28,9 +28,18 @@ io_progInit(const char *progName, u_int initNum, u_int prg->prog_maxn = maxNum; strlcpy(prg->prog_name, progName, sizeof prg->prog_name); + prg->prog_used = e_malloc(E_ALIGN(prg->prog_maxn, sizeof *prg->prog_used) / + sizeof *prg->prog_used); + if (!prg->prog_used) { + io_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + e_free(prg); + return NULL; + } + prg->prog_fds = array_Init(prg->prog_maxn); if (!prg->prog_fds) { io_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + e_free(prg->prog_used); e_free(prg); return NULL; } @@ -58,6 +67,7 @@ io_progDestroy(prog_t ** __restrict pprg) io_progClose(*pprg, 0); + e_free((*pprg)->prog_used); array_Destroy(&(*pprg)->prog_fds); pthread_mutex_destroy(&(*pprg)->prog_mtx); @@ -89,8 +99,13 @@ io_progClose(prog_t * __restrict prg, u_int closeNum) for (i = array_Size(prg->prog_fds) - 1; (closeNum ? ret < closeNum : 42) && i > -1; i--) if (array_Get(prg->prog_fds, i)) { +#ifdef POPEN_STREAM e_pclose(array(prg->prog_fds, i, FILE*)); +#else + e_pclose((int) array(prg->prog_fds, i, intptr_t)); +#endif array_Del(prg->prog_fds, i, 0); + clrbit(prg->prog_used, i); prg->prog_cnum--; ret++; } @@ -109,14 +124,18 @@ io_progClose(prog_t * __restrict prg, u_int closeNum) int io_progOpen(prog_t * __restrict prg, u_int execNum) { +#ifdef POPEN_STREAM FILE *f; +#else + int f; +#endif int stat, ret = 0; register int i; pid_t pid; if (!prg) return 0; - if (execNum > prg->prog_maxn) { + if (prg->prog_cnum + execNum > prg->prog_maxn) { io_SetErr(EINVAL, "Requested number for program execution is over pool's limit"); return 0; } @@ -125,7 +144,11 @@ io_progOpen(prog_t * __restrict prg, u_int execNum) for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++) if (!array_Get(prg->prog_fds, i)) { f = e_popen(prg->prog_name, "r+", &pid); +#ifdef POPEN_STREAM if (!f) { +#else + if (f == -1) { +#endif LOGERR; ret = -1; break; @@ -145,6 +168,28 @@ io_progOpen(prog_t * __restrict prg, u_int execNum) } /* + * io_progGrow() - Execute to number of programs in pool + * + * @prg = program pool + * @toNum = execute to number of programs (0 max) + * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error + */ +int +io_progGrow(prog_t * __restrict prg, u_int toNum) +{ + if (!prg) + return 0; + if (toNum > prg->prog_maxn) { + io_SetErr(EINVAL, "Requested number for program execution is over pool's limit"); + return 0; + } + if (!toNum) + toNum = prg->prog_maxn; + + return io_progOpen(prg, toNum - prg->prog_cnum); +} + +/* * io_progVacuum() - Vacuum pool to running number of programs * * @prg = program pool @@ -168,8 +213,12 @@ io_progVacuum(prog_t * __restrict prg, u_int toNum) 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)) { + if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) { +#ifdef POPEN_STREAM e_pclose(array(prg->prog_fds, i, FILE*)); +#else + e_pclose((int) array(prg->prog_fds, i, intptr_t)); +#endif array_Del(prg->prog_fds, i, 0); prg->prog_cnum--; ret++; @@ -177,4 +226,112 @@ io_progVacuum(prog_t * __restrict prg, u_int toNum) pthread_mutex_unlock(&prg->prog_mtx); return ret; +} + +/* + * io_progCheck() - Check exit status of program pool + * + * @prg = program pool + * return: -1 error or >-1 exited programs + */ +int +io_progCheck(prog_t * __restrict prg) +{ + int ret = 0; + struct tagPIOPID *p; + register int i; + + if (!prg) + return -1; + + pthread_mutex_lock(&prg->prog_mtx); + for (i = 0; i < array_Size(prg->prog_fds); i++) + if (array_Get(prg->prog_fds, i) && +#ifdef POPEN_STREAM + (p = pio_pgetpid(array(prg->prog_fds, i, FILE*)))) +#else + (p = pio_pgetpid((int) array(prg->prog_fds, i, intptr_t)))) +#endif + if (waitpid(p->pid, &p->stat, WNOHANG) > 0) { + clrbit(prg->prog_used, i); + ret++; + } + pthread_mutex_unlock(&prg->prog_mtx); + + return ret; +} + +/* + * io_progAttach() - Attach to open program + * + * @prg = program pool + * return: NULL error or !=NULL attached program handle + */ +#ifdef POPEN_STREAM +FILE * +#else +int +#endif +io_progAttach(prog_t * __restrict prg) +{ +#ifdef POPEN_STREAM + FILE *f = NULL; +#else + int f = -1; +#endif + register int i; + + if (!prg) +#ifdef POPEN_STREAM + return NULL; +#else + return -1; +#endif + + pthread_mutex_lock(&prg->prog_mtx); + for (i = 0; i < array_Size(prg->prog_fds); i++) + if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) { + setbit(prg->prog_used, i); +#ifdef POPEN_STREAM + f = array(prg->prog_fds, i, FILE*); +#else + f = array(prg->prog_fds, i, intptr_t); +#endif + break; + } + pthread_mutex_unlock(&prg->prog_mtx); + + return f; +} + +/* + * io_progDetach() - Detch from open program + * + * @prg= program pool + * @pfd = attached program handle + * return: none + */ +void +#ifdef POPEN_STREAM +io_progDetach(prog_t * __restrict prg, FILE *pfd) +#else +io_progDetach(prog_t * __restrict prg, int pfd) +#endif +{ + register int i; + + if (!prg || !pfd) + return; + + pthread_mutex_lock(&prg->prog_mtx); + for (i = 0; i < array_Size(prg->prog_fds); i++) +#ifdef POPEN_STREAM + if (array(prg->prog_fds, i, FILE*) == pfd) { +#else + if (array(prg->prog_fds, i, intptr_t) == pfd) { +#endif + clrbit(prg->prog_used, i); + break; + } + pthread_mutex_unlock(&prg->prog_mtx); }