Annotation of libaitio/src/exec.c, revision 1.1.2.9

1.1.2.1   misho       1: #include "global.h"
                      2: 
                      3: 
                      4: /*
                      5:  * io_progInit() - Init program pool
                      6:  *
                      7:  * @progName = program name for execution
                      8:  * @initNum = initial started programs
                      9:  * @maxNum = maximum started programs
                     10:  * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy())
                     11:  */
                     12: prog_t *
                     13: io_progInit(const char *progName, u_int initNum, u_int maxNum)
                     14: {
                     15:        prog_t *prg = NULL;
                     16: 
                     17:        if (initNum > maxNum)
                     18:                return NULL;
                     19: 
                     20:        prg = e_malloc(sizeof(prog_t));
                     21:        if (!prg) {
                     22:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                     23:                return NULL;
                     24:        } else
                     25:                memset(prg, 0, sizeof(prog_t));
                     26: 
                     27:        prg->prog_inin = initNum;
                     28:        prg->prog_maxn = maxNum;
                     29:        strlcpy(prg->prog_name, progName, sizeof prg->prog_name);
                     30: 
1.1.2.9 ! misho      31:        prg->prog_used = e_malloc(E_ALIGN(prg->prog_maxn, sizeof *prg->prog_used) / 
        !            32:                        sizeof *prg->prog_used);
        !            33:        if (!prg->prog_used) {
        !            34:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
        !            35:                e_free(prg);
        !            36:                return NULL;
        !            37:        }
        !            38: 
1.1.2.1   misho      39:        prg->prog_fds = array_Init(prg->prog_maxn);
                     40:        if (!prg->prog_fds) {
                     41:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.1.2.9 ! misho      42:                e_free(prg->prog_used);
1.1.2.1   misho      43:                e_free(prg);
                     44:                return NULL;
                     45:        }
                     46: 
                     47:        pthread_mutex_init(&prg->prog_mtx, NULL);
1.1.2.2   misho      48: 
1.1.2.6   misho      49:        if (io_progOpen(prg, prg->prog_inin) < 0) {
1.1.2.2   misho      50:                io_progDestroy(&prg);
1.1.2.6   misho      51:                prg = NULL;
                     52:        }
1.1.2.1   misho      53:        return prg;
                     54: }
                     55: 
                     56: /*
                     57:  * io_progDestroy() - Destroy entire program pool
                     58:  *
                     59:  * @pprg = program pool
                     60:  * return: none
                     61:  */
                     62: void
                     63: io_progDestroy(prog_t ** __restrict pprg)
                     64: {
                     65:        if (!pprg || !*pprg)
                     66:                return;
                     67: 
                     68:        io_progClose(*pprg, 0);
                     69: 
1.1.2.9 ! misho      70:        e_free((*pprg)->prog_used);
1.1.2.1   misho      71:        array_Destroy(&(*pprg)->prog_fds);
                     72:        pthread_mutex_destroy(&(*pprg)->prog_mtx);
                     73: 
                     74:        e_free(*pprg);
                     75:        *pprg = NULL;
                     76: }
                     77: 
                     78: /*
                     79:  * io_progClose() - Close all programs in pool
                     80:  *
                     81:  * @prg = program pool
                     82:  * @closeNum = close program(s) (0 all)
                     83:  * return: 0 error, >0 closed programs
                     84:  */
                     85: int
                     86: io_progClose(prog_t * __restrict prg, u_int closeNum)
                     87: {
                     88:        register int i;
                     89:        int ret = 0;
                     90: 
                     91:        if (!prg)
                     92:                return 0;
                     93:        if (closeNum > prg->prog_maxn) {
                     94:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                     95:                return 0;
                     96:        }
                     97: 
                     98:        pthread_mutex_lock(&prg->prog_mtx);
                     99:        for (i = array_Size(prg->prog_fds) - 1; 
                    100:                        (closeNum ? ret < closeNum : 42) && i > -1; i--)
                    101:                if (array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     102:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho     103:                        array_Del(prg->prog_fds, i, 0);
1.1.2.9 ! misho     104:                        clrbit(prg->prog_used, i);
1.1.2.1   misho     105:                        prg->prog_cnum--;
                    106:                        ret++;
                    107:                }
                    108:        pthread_mutex_unlock(&prg->prog_mtx);
                    109: 
                    110:        return ret;
                    111: }
                    112: 
                    113: /*
                    114:  * io_progOpen() - Execute number of program(s)
                    115:  *
                    116:  * @prg = program pool
                    117:  * @execNum = execute program(s) (0 max)
                    118:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    119:  */
                    120: int
                    121: io_progOpen(prog_t * __restrict prg, u_int execNum)
                    122: {
                    123:        FILE *f;
1.1.2.4   misho     124:        int stat, ret = 0;
1.1.2.1   misho     125:        register int i;
1.1.2.4   misho     126:        pid_t pid;
1.1.2.1   misho     127: 
                    128:        if (!prg)
                    129:                return 0;
1.1.2.8   misho     130:        if (prg->prog_cnum + execNum > prg->prog_maxn) {
1.1.2.1   misho     131:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    132:                return 0;
                    133:        }
                    134: 
                    135:        pthread_mutex_lock(&prg->prog_mtx);
                    136:        for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
                    137:                if (!array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     138:                        f = e_popen(prg->prog_name, "r+", &pid);
1.1.2.1   misho     139:                        if (!f) {
                    140:                                LOGERR;
1.1.2.5   misho     141:                                ret = -1;
1.1.2.1   misho     142:                                break;
1.1.2.6   misho     143:                        } else if (waitpid(pid, &stat, WNOHANG)) {
                    144:                                io_SetErr(ECHILD, "Program with pid=%d exit with status %d", 
                    145:                                                pid, WIFEXITED(stat) ? WEXITSTATUS(stat) : -1);
1.1.2.5   misho     146:                                ret = -1;
1.1.2.4   misho     147:                                break;
1.1.2.1   misho     148:                        } else
                    149:                                array_Set(prg->prog_fds, i, f);
                    150:                        prg->prog_cnum++;
                    151:                        ret++;
                    152:                }
                    153:        pthread_mutex_unlock(&prg->prog_mtx);
                    154: 
                    155:        return ret;
                    156: }
                    157: 
                    158: /*
1.1.2.8   misho     159:  * io_progGrow() - Execute to number of programs in pool
                    160:  *
                    161:  * @prg = program pool
                    162:  * @toNum = execute to number of programs (0 max)
                    163:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    164:  */
                    165: int
                    166: io_progGrow(prog_t * __restrict prg, u_int toNum)
                    167: {
                    168:        if (!prg)
                    169:                return 0;
                    170:        if (toNum > prg->prog_maxn) {
                    171:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    172:                return 0;
                    173:        }
                    174:        if (!toNum)
                    175:                toNum = prg->prog_maxn;
                    176: 
                    177:        return io_progOpen(prg, toNum - prg->prog_cnum);
                    178: }
                    179: 
                    180: /*
1.1.2.1   misho     181:  * io_progVacuum() - Vacuum pool to running number of programs
                    182:  *
                    183:  * @prg = program pool
                    184:  * @toNum = vacuum to number of programs (0 to init number)
                    185:  * return: 0 error or >0 closed programs
                    186:  */
                    187: int
                    188: io_progVacuum(prog_t * __restrict prg, u_int toNum)
                    189: {
                    190:        register int i;
                    191:        int ret = 0;
                    192: 
                    193:        if (!prg)
                    194:                return 0;
                    195:        if (toNum > prg->prog_maxn) {
                    196:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                    197:                return 0;
                    198:        }
                    199:        if (!toNum)
                    200:                toNum = prg->prog_inin;
                    201: 
                    202:        pthread_mutex_lock(&prg->prog_mtx);
                    203:        for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
1.1.2.9 ! misho     204:                if (array_Get(prg->prog_fds, i) && isset(prg->prog_used, i)) {
1.1.2.6   misho     205:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho     206:                        array_Del(prg->prog_fds, i, 0);
1.1.2.9 ! misho     207:                        clrbit(prg->prog_used, i);
1.1.2.1   misho     208:                        prg->prog_cnum--;
                    209:                        ret++;
                    210:                }
                    211:        pthread_mutex_unlock(&prg->prog_mtx);
                    212: 
                    213:        return ret;
                    214: }
1.1.2.7   misho     215: 
                    216: /*
                    217:  * io_progCheck() - Check exit status of program pool
                    218:  *
                    219:  * @prg = program pool
                    220:  * return: -1 error or >-1 exited programs
                    221:  */
                    222: int
                    223: io_progCheck(prog_t * __restrict prg)
                    224: {
                    225:        int ret = 0;
                    226:        struct tagPIOPID *p;
                    227:        register int i;
                    228: 
                    229:        if (!prg)
                    230:                return -1;
                    231: 
1.1.2.9 ! misho     232:        pthread_mutex_lock(&prg->prog_mtx);
1.1.2.7   misho     233:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    234:                if (array_Get(prg->prog_fds, i) && 
                    235:                                (p = pio_pgetpid(array(prg->prog_fds, i, FILE*))))
1.1.2.9 ! misho     236:                        if (waitpid(p->pid, &p->stat, WNOHANG) > 0) {
        !           237:                                clrbit(prg->prog_used, i);
1.1.2.7   misho     238:                                ret++;
1.1.2.9 ! misho     239:                        }
        !           240:        pthread_mutex_unlock(&prg->prog_mtx);
1.1.2.7   misho     241: 
                    242:        return ret;
                    243: }
1.1.2.9 ! misho     244: 
        !           245: /*
        !           246:  * io_progAttach() - Attach to open program
        !           247:  *
        !           248:  * @prg = program pool
        !           249:  * return: NULL error or !=NULL attached program handle
        !           250:  */
        !           251: FILE *
        !           252: io_progAttach(prog_t * __restrict prg)
        !           253: {
        !           254:        FILE *f = NULL;
        !           255:        register int i;
        !           256: 
        !           257:        if (!prg)
        !           258:                return NULL;
        !           259: 
        !           260:        pthread_mutex_lock(&prg->prog_mtx);
        !           261:        for (i = 0; i < array_Size(prg->prog_fds); i++)
        !           262:                if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) {
        !           263:                        setbit(prg->prog_used, i);
        !           264:                        f = array(prg->prog_fds, i, FILE*);
        !           265:                        break;
        !           266:                }
        !           267:        pthread_mutex_unlock(&prg->prog_mtx);
        !           268: 
        !           269:        return f;
        !           270: }
        !           271: 
        !           272: /*
        !           273:  * io_progDetach() - Detch from open program
        !           274:  *
        !           275:  * @prg= program pool
        !           276:  * @pfd = attached program handle
        !           277:  * return: none
        !           278:  */
        !           279: void
        !           280: io_progDetach(prog_t * __restrict prg, FILE *pfd)
        !           281: {
        !           282:        register int i;
        !           283: 
        !           284:        if (!prg || !pfd)
        !           285:                return;
        !           286: 
        !           287:        pthread_mutex_lock(&prg->prog_mtx);
        !           288:        for (i = 0; i < array_Size(prg->prog_fds); i++)
        !           289:                if (array(prg->prog_fds, i, FILE*) == pfd) {
        !           290:                        clrbit(prg->prog_used, i);
        !           291:                        break;
        !           292:                }
        !           293:        pthread_mutex_unlock(&prg->prog_mtx);
        !           294: }

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