zan-extension/src/workers/zanMaster.c
///TODO::: wait and respawn child process
:: wait and respawn child process
:: wait and respawn child process
int zan_master_process_loop(zanServer *serv)
{
    int status = 0;
    zan_pid_t pid = -1;
    zan_pid_t new_pid = -1;
    int index = 0;
    int reloadworker_index = 0;
    int result = -1;
    ServerG.use_signalfd = 0;
    ServerG.use_timerfd = 0;
    memset(&MasterProcess, 0, sizeof(MasterProcess));
    zan_setproctitle("master:", 1);
    if (serv->onStart)
    {
        serv->onStart(serv);
    }
    unsigned int reloadworker_num = ServerG.servSet.worker_num + ServerG.servSet.task_worker_num + ServerG.servSet.net_worker_num;
    if(reloadworker_num == 0)
    {
        zanError("No worker running");
        return ZAN_ERR;
    }
    zanWorker *reload_workers = sw_calloc(reloadworker_num, sizeof(zanWorker));
    if(NULL == reload_workers)
    {
        zanError("malloc[reload_workers] failed");
        return ZAN_ERR;
    }
    swSignal_add(SIGHUP, NULL);
    swSignal_add(SIGTERM, zanMaster_signalhandle);
    swSignal_add(SIGINT, zanMaster_signalhandle);
    swSignal_add(SIGQUIT, zanMaster_signalhandle);
    swSignal_add(SIGUSR1, zanMaster_signalhandle);
    swSignal_add(SIGUSR2, zanMaster_signalhandle);
#ifdef SIGRTMIN
    swSignal_add(SIGRTMIN, zanMaster_signalhandle);
#endif
    if(ServerG.main_reactor != NULL)
    {
        ServerG.main_reactor = NULL;
    }
    while (ServerG.running > 0)
    {
        pid = -1;
        status = 0;
        pid = wait(&status);
        zanDebug("ServerG.running=%d, process_type=%d, master_pid=%d,pid=%d", ServerG.running, ServerG.process_type, ServerGS->master_pid, pid);
        if (pid < 0)
        {
            zanDebug("wait error, pid=%d", pid);
            if (MasterProcess.reloading == 0)
            {
                zanTrace("wait() failed. Error: %s [%d]", strerror(errno), errno);
            }
            else if(MasterProcess.reload_event_worker == 1)
            {
                zanDebug("Server is reloading event_worker now.");
                memset(reload_workers, 0, sizeof(zanWorker)*reloadworker_num);
                memcpy(reload_workers, ServerGS->event_workers.workers, sizeof(zanWorker) * ServerG.servSet.worker_num);
                reloadworker_num = ServerG.servSet.worker_num;
                if (ServerG.servSet.task_worker_num > 0)
                {
                    memcpy(reload_workers + ServerG.servSet.worker_num, ServerGS->task_workers.workers, sizeof(zanWorker) * ServerG.servSet.task_worker_num);
                    reloadworker_num += ServerG.servSet.task_worker_num;
                }
                reloadworker_index = 0;
            }
            else if(MasterProcess.reload_task_worker == 1)
            {
                zanDebug("Server is reloading task_worker now.");
                memset(reload_workers, 0, sizeof(zanWorker)*reloadworker_num);
                if (ServerG.servSet.task_worker_num == 0)
                {
                    zanWarn("cannot reload workers, because server no have task workers.");
                    continue;
                }
                memcpy(reload_workers, ServerGS->task_workers.workers, sizeof(zanWorker) * ServerG.servSet.task_worker_num);
                reloadworker_num = ServerG.servSet.task_worker_num;
                reloadworker_index = 0;
            }
            else
            {
                zanWarn("signal is not right");
                break;
            }
        }
        else if((pid > 0) && (ServerG.running == 1))
        {
            index = 0;
            new_pid = zanrelaod_worker(&index, status, ZAN_PROCESS_WORKER, serv, &pid, &(ServerGS->event_workers));
            if(pid > 0)
            {
                new_pid = zanrelaod_worker(&index, status, ZAN_PROCESS_TASKWORKER, serv, &pid, &(ServerGS->task_workers));
            }
            if(pid > 0)
            {
                new_pid = zanrelaod_worker(&index, status, ZAN_PROCESS_NETWORKER, serv, &pid, &(ServerGS->net_workers));
            }
            if(serv->user_worker_map != NULL)
            {
                zanMaster_waituserworker(&(ServerGS->event_workers), pid);
            }
        }
        else
        {
            zanDebug("server is not running");
            break;
        }
        if((MasterProcess.reload_event_worker == 1 )|| (MasterProcess.reload_task_worker == 1))
        {
            result = zanworker_freeprocess(&reloadworker_index, reload_workers, reloadworker_num);
            if(result < 0)
            {
                zanWarn("kill workers failed");
            }
        }
    }
    sw_free(reload_workers);
    if(ServerG.servSet.worker_num > 0)
    {
        zan_worker_shutdown(&ServerGS->event_workers);
    }
    if (ServerG.servSet.task_worker_num > 0)
    {
        zan_processpool_shutdown(&ServerGS->task_workers);
    }
    if(ServerG.servSet.net_worker_num > 0)
    {
        zan_networker_shutdown(&ServerGS->net_workers);
    }
    if (serv->user_worker_map)
    {
        zanWorker* user_worker = NULL;
        uint64_t key = 0;
        while (1)
        {
            user_worker = swHashMap_each_int(serv->user_worker_map, &key);
            if (user_worker == NULL)
            {
                break;
            }
            swKill(user_worker->worker_pid, SIGTERM);
        }
        while (1)
        {
            user_worker = swHashMap_each_int(serv->user_worker_map, &key);
            if (user_worker == NULL)
            {
                break;
            }
            if (swWaitpid(user_worker->worker_pid, &status, 0) < 0)
            {
                zanSysError("waitpid(%d) failed.", user_worker->worker_pid);
            }
        }
    }
    return ZAN_ERR;
}
int zan_master_process_loop ( zanServer * serv ) { int status = 0 ; zan_pid_t pid = -1 ; zan_pid_t new_pid = -1 ; int index = 0 ; int reloadworker_index = 0 ; int result = -1 ; ServerG . use_signalfd = 0 ; ServerG . use_timerfd = 0 ; memset ( & MasterProcess , 0 , sizeof ( MasterProcess ) ) ; zan_setproctitle ( " " , 1 ) ; if ( serv -> onStart ) { serv -> onStart ( serv ) ; } unsigned int reloadworker_num = ServerG . servSet . worker_num + ServerG . servSet . task_worker_num + ServerG . servSet . net_worker_num ; if ( reloadworker_num == 0 ) { zanError ( " " ) ; return ZAN_ERR ; } zanWorker * reload_workers = sw_calloc ( reloadworker_num , sizeof ( zanWorker ) ) ; if ( NULL == reload_workers ) { zanError ( " " ) ; return ZAN_ERR ; } swSignal_add ( SIGHUP , NULL ) ; swSignal_add ( SIGTERM , zanMaster_signalhandle ) ; swSignal_add ( SIGINT , zanMaster_signalhandle ) ; swSignal_add ( SIGQUIT , zanMaster_signalhandle ) ; swSignal_add ( SIGUSR1 , zanMaster_signalhandle ) ; swSignal_add ( SIGUSR2 , zanMaster_signalhandle ) ; #ifdef SIGRTMIN swSignal_add ( SIGRTMIN , zanMaster_signalhandle ) ; #endif if ( ServerG . main_reactor != NULL ) { ServerG . main_reactor = NULL ; } while ( ServerG . running > 0 ) { pid = -1 ; status = 0 ; pid = wait ( & status ) ; zanDebug ( " " , ServerG . running , ServerG . process_type , ServerGS -> master_pid , pid ) ; if ( pid < 0 ) { zanDebug ( " " , pid ) ; if ( MasterProcess . reloading == 0 ) { zanTrace ( " " , strerror ( errno ) , errno ) ; } else if ( MasterProcess . reload_event_worker == 1 ) { zanDebug ( " " ) ; memset ( reload_workers , 0 , sizeof ( zanWorker ) * reloadworker_num ) ; memcpy ( reload_workers , ServerGS -> event_workers . workers , sizeof ( zanWorker ) * ServerG . servSet . worker_num ) ; reloadworker_num = ServerG . servSet . worker_num ; if ( ServerG . servSet . task_worker_num > 0 ) { memcpy ( reload_workers + ServerG . servSet . worker_num , ServerGS -> task_workers . workers , sizeof ( zanWorker ) * ServerG . servSet . task_worker_num ) ; reloadworker_num += ServerG . servSet . task_worker_num ; } reloadworker_index = 0 ; } else if ( MasterProcess . reload_task_worker == 1 ) { zanDebug ( " " ) ; memset ( reload_workers , 0 , sizeof ( zanWorker ) * reloadworker_num ) ; if ( ServerG . servSet . task_worker_num == 0 ) { zanWarn ( " " ) ; continue ; } memcpy ( reload_workers , ServerGS -> task_workers . workers , sizeof ( zanWorker ) * ServerG . servSet . task_worker_num ) ; reloadworker_num = ServerG . servSet . task_worker_num ; reloadworker_index = 0 ; } else { zanWarn ( " " ) ; break ; } } else if ( ( pid > 0 ) && ( ServerG . running == 1 ) ) { index = 0 ; new_pid = zanrelaod_worker ( & index , status , ZAN_PROCESS_WORKER , serv , & pid , & ( ServerGS -> event_workers ) ) ; if ( pid > 0 ) { new_pid = zanrelaod_worker ( & index , status , ZAN_PROCESS_TASKWORKER , serv , & pid , & ( ServerGS -> task_workers ) ) ; } if ( pid > 0 ) { new_pid = zanrelaod_worker ( & index , status , ZAN_PROCESS_NETWORKER , serv , & pid , & ( ServerGS -> net_workers ) ) ; } if ( serv -> user_worker_map != NULL ) { zanMaster_waituserworker ( & ( ServerGS -> event_workers ) , pid ) ; } } else { zanDebug ( " " ) ; break ; } if ( ( MasterProcess . reload_event_worker == 1 ) || ( MasterProcess . reload_task_worker == 1 ) ) { result = zanworker_freeprocess ( & reloadworker_index , reload_workers , reloadworker_num ) ; if ( result < 0 ) { zanWarn ( " " ) ; } } } sw_free ( reload_workers ) ; if ( ServerG . servSet . worker_num > 0 ) { zan_worker_shutdown ( & ServerGS -> event_workers ) ; } if ( ServerG . servSet . task_worker_num > 0 ) { zan_processpool_shutdown ( & ServerGS -> task_workers ) ; } if ( ServerG . servSet . net_worker_num > 0 ) { zan_networker_shutdown ( & ServerGS -> net_workers ) ; } if ( serv -> user_worker_map ) { zanWorker * user_worker = NULL ; uint64_t key = 0 ; while ( 1 ) { user_worker = swHashMap_each_int ( serv -> user_worker_map , & key ) ; if ( user_worker == NULL ) { break ; } swKill ( user_worker -> worker_pid , SIGTERM ) ; } while ( 1 ) { user_worker = swHashMap_each_int ( serv -> user_worker_map , & key ) ; if ( user_worker == NULL ) { break ; } if ( swWaitpid ( user_worker -> worker_pid , & status , 0 ) < 0 ) { zanSysError ( " " , user_worker -> worker_pid ) ; } } } return ZAN_ERR ; }
TODO::: wait and respawn child process
TODO ::: wait and respawn child process
//zanWarn("call server onStart"); //init reload worker //for reload //reload task_worker //reload net_worker //zanDebug("wait success, child pid=%d exit, status=%d", pid, status); //kill all child process //kill and wait task process //kill and wait net process //kill user process //has hmap empty //wait user process //hashmap empty