4.4.3 single_server_wakeup函数:执行业务模块回调函数

来源:互联网 发布:nc软件下载 编辑:程序博客网 时间:2024/05/27 21:04

经过诸多的设置与判断,在single_server_wakeup函数中,针对来自网络的请求为业务模块执行其回调函数。

/master/single_server.c252 /* single_server_wakeup - wake upapplication */253254 static void single_server_wakeup(intfd, HTABLE *attr)255 {256    VSTREAM *stream;257    char   *tmp;258259    /*260     * If the accept() succeeds, be sure to disable non-blocking I/O, because261     * the application is supposed to be single-threaded. Notice the master262     * of our (un)availability to service connection requests. Commit suicide263     * when the master process disconnected from us. Don't drop the already264     * accepted client request after "postfix reload"; that wouldbe rude.265     */266    if (msg_verbose)267        msg_info("connection established");268    non_blocking(fd, BLOCKING);269    close_on_exec(fd, CLOSE_ON_EXEC);270    stream = vstream_fdopen(fd, O_RDWR);271    tmp = concatenate(single_server_name, " socket", (char *) 0);272    vstream_control(stream,273                     CA_VSTREAM_CTL_PATH(tmp),274                    CA_VSTREAM_CTL_CONTEXT((void *) attr),275                     CA_VSTREAM_CTL_END);276    myfree(tmp);277    timed_ipc_setup(stream);278    if (master_notify(var_pid, single_server_generation, MASTER_STAT_TAKEN)< 0)279         /* void */ ;280    if (single_server_in_flow_delay && mail_flow_get(1) < 0)281        doze(var_in_flow_delay * 1000000);282    single_server_service(stream, single_server_name, single_server_argv);283    (void) vstream_fclose(stream);284    if (master_notify(var_pid, single_server_generation, MASTER_STAT_AVAIL)< 0)285        single_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);286    if (msg_verbose)287        msg_info("connection closed");288    /* Avoid integer wrap-around in a persistent process.  */289    if (use_count < INT_MAX)290        use_count++;291    if (var_idle_limit > 0)292        event_request_timer(single_server_timeout, (void *) 0, var_idle_limit);293    if (attr)294        htable_free(attr, myfree);295 }

278-285 注意这里的master_notify调用顺序

根据4.2节的master_spawn函数,父进程认为新建子进程的avail状态为可用。

这里我们要通知父进程通过status_fd管道更新子进程状态信息。

 

278 在执行回调函数前,因为我们马上就要处理这个新请求了,通知父进程该子进程状态为MASTER_STAT_TAKEN。

 

280-281 收信进程(smtpd)执行速度受制于发信进程的速度——如果mail_flow_get(1)取值失败(见4.1.3.3和6.2节),说明发信过程延迟,调用doze函数进行延时,以免服务器累积太多信件:

/util/doze.c42 /* doze - sleep a while */ 43 44void    doze(unsigned delay) 51{   tv.tv_usec = delay % MILLION; 52    while (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv) <0) 53        if (errno != EINTR) 54            msg_fatal("doze: select: %m"); 55 }

282执行业务模块传入的回调函数。

 

284该请求执行完毕,通知父进程这个子进程的状态又变为MASTER_STAT_AVAIL。

0 0
原创粉丝点击