地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【C】signalfd + epoll のサンプル

typedef enum {
    MYOP_ERROR = -1,
    MYOP_NONE = 0,  
    MYOP_QUIT,
    MYOP_WAITCHILD,
    /* snip */
} MyOperation_t;

/**
 *  AnalyseEvent - epoll_eventから任意のコマンドIDを導く
 */
MyOperation_t AnalyseEvent (struct epoll_event *event)
{
    if (event->data.fd == sigFD) {
        struct signalfd_siginfo info = {0};
        read (sigFD, &info, sizeof(info));

        switch (info.ssi_signo) {
        case SIGINT:
        case SIGTERM:
            return MYOP_QUIT;
        case SIGCHLD:
            return MYOP_WAITCHILD;
        default:
            break;
        }
    }
    else if (event->data.fd == cliFD) {
        /* snip */
    }
    /* else if (event->data.fd == any_other_fd) { ... } */
    return MYOP_NONE;
}

/**
 *  DispatchEvent - 指定されたコマンドIDによる処理分岐
 */
void DispatchEvent (MyOperation_t mycmd)
{
    switch (mycmd) {
    case MYOP_QUIT:
        done = true;
        break;
    case MYOP_WAITCHILD:
        WaitChild ();
        break;

    default:
        break;
    }
    return ;
}

/**
 *  EpollLoop - イベント待ちおよびイベント発生時の処理起動
 */
void EpollLoop (void)
{
    while (!done) {
        struct epoll_event ev = {0};
        int evnum = epoll_wait (epollFD, &ev, 1, -1);
        for (int i=0; i<evnum; ++i) {
            MyOperation_t mycmd = AnalyseEvent (&ev);
            DispatchEvent (mycmd);
        }
    }
    return ;
}