4.3.3.3 master_status_event函数:父进程读status_fd管道,更新其记录的子进程状态

来源:互联网 发布:网络加速的原理 编辑:程序博客网 时间:2024/05/18 00:03

/master/master_status.c58 /* master_status_event - status read event handler */ 59 60static void master_status_event(int event, void *context) 61 { 62    const char *myname = "master_status_event"; 63    MASTER_SERV *serv = (MASTER_SERV *) context; 64    MASTER_STATUS stat; 65    MASTER_PROC *proc; 66    MASTER_PID pid; 67    int     n; 68 69    if (event == 0)                             /* XXX Can thishappen?  */ 70        return; 71 72    /* 73     * We always keep the child end of the status pipe open, so an EOF read 74     * condition means that we're seriously confused. We use non-blocking 75     * reads so that we don't get stuck when someone sends a partial message. 76     * Messages are short, so a partial read means someone wrote less than a 77     * whole status message. Hopefully the next read will be in sync again... 78     * We use a global child process status table because when a child dies 79     * only its pid is known - we do not know what service it came from. 80     */ 81    switch (n = read(serv->status_fd[0], (void *) &stat,sizeof(stat))) { 82 83    case -1: 84        msg_warn("%s: read: %m", myname); 85        return; 86 87    case 0: 88        msg_panic("%s: read EOF status", myname);

83-88 错误处理。

 89        /* NOTREACHED */ 90 91    default: 92        msg_warn("service %s(%s): child (pid %d) sent partial status update(%d bytes)", 93                  serv->ext_name,serv->name, stat.pid, n); 94        return; 95 96    case sizeof(stat): 97        pid = stat.pid; 98        if (msg_verbose) 99            msg_info("%s: pid %d gen %u avail %d",100                      myname, stat.pid,stat.gen, stat.avail);101    }102103    /*104     * Sanity checks. Do not freak out when the child sends garbage because105     * it is confused or for other reasons. However, be sure to freak out106     * when our own data structures are inconsistent. A process not found107     * condition can happen when we reap a process before receiving its108     * status update, so this is not an error.109     */110    if ((proc = (MASTER_PROC *) binhash_find(master_child_table,111                                         (void*) &pid, sizeof(pid))) == 0) {112        if (msg_verbose)113             msg_info("%s: process id notfound: %d", myname, stat.pid);114        return;115    }

 

110-115 找到子进程对应的MASTER_PROC结构体。

116    if (proc->gen != stat.gen) {117        msg_info("ignoring status update from child pid %d generation%u",118                  pid, stat.gen);119        return;120    }121    if (proc->serv != serv)122        msg_panic("%s: pointer corruption: %p != %p",123                   myname, (void *)proc->serv, (void *) serv);124125    /*126     * Update our idea of the child process status. Allow redundant status127     * updates, because different types of events may be processed out of128     * order. Otherwise, warn about weird status updates but do not take129     * action. It's all gossip after all.130     */131    if (proc->avail == stat.avail)132        return;133    switch (stat.avail) {134    case MASTER_STAT_AVAIL:135        proc->use_count++;136        master_avail_more(serv, proc);137        break;138    case MASTER_STAT_TAKEN:139        master_avail_less(serv, proc);140        break;

 

131-140 根据子进程通过管道发来的状态报告,更新父进程中保留的MASTER_PROC结构体状态。

141    default:142        msg_warn("%s: ignoring unknown status: %d allegedly from pid:%d",143                  myname, stat.pid,stat.avail);144        break;145    }146 }

 

在4.2节,父进程新建子进程后将子进程状态设为可用。

 

在4.4.3节,子进程在处理新请求前,通知父进程其状态为已用。处理完新请求后,通知父进程其状态为可用。所以这里父进程根据子进程的通知更新子进程状态。
0 0
原创粉丝点击