LoginSignup
1
1

More than 5 years have passed since last update.

neoagent1人読書会 その8

Posted at

今回はKVSからのレスポンスをウェブアプリケーションに書き出す部分。「その5」で見たna_client_callbackの残り半分を読んでいく。

static void na_client_callback(EV_P_ struct ev_io *w, int revents)
{
    int cfd, tsfd, size;
    na_client_t *client;
    na_env_t *env;

    cfd    = w->fd;
    client = (na_client_t *)w->data;
    env    = client->env;
    tsfd   = client->tsfd;

    pthread_rwlock_rdlock(&env->lock_refused);
    if ((client->is_refused_active != env->is_refused_active) || env->is_refused_accept) {
        pthread_rwlock_unlock(&env->lock_refused);
        NA_EVENT_FAIL(NA_ERROR_INVALID_CONNPOOL, EV_A, w, client, env);
        return; // request fail
    }
    pthread_rwlock_unlock(&env->lock_refused);

    if (env->loop_max > 0 && client->loop_cnt++ > env->loop_max) {
        NA_EVENT_FAIL(NA_ERROR_OUTOF_LOOP, EV_A, w, client, env);
        return; // request fail
    }

    if (revents & EV_READ) {

..

    } else if (revents & EV_WRITE) {

ここまではいつもどおり。

        size = write(cfd,
                     client->srbuf + client->cwbufsize,
                     client->srbufsize - client->cwbufsize);

        if (size < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
                return; // not ready yet
            }
            if (errno == EPIPE) {
                NA_EVENT_FAIL(NA_ERROR_BROKEN_PIPE, EV_A, w, client, env);
            } else {
                NA_EVENT_FAIL(NA_ERROR_FAILED_WRITE, EV_A, w, client, env);
            }
            return; // request fail
        }

        client->cwbufsize += size;

ここも特におかしいところはない。

  • srbuf: レスポンスバッファーの先頭を指すポインター
  • srbufsize: レスポンスバッファーのうち実際に使われているバイト数
  • cwbufsize: レスポンスバッファーのうち書き出しが終わったバイト数
        if (client->cwbufsize < client->srbufsize) {
            na_event_switch(EV_A_ w, &client->c_watcher, cfd, EV_WRITE);
            return;
        } else {
            client->crbufsize        = 0;
            client->cwbufsize        = 0;
            client->srbufsize        = 0;
            client->swbufsize        = 0;
            client->request_bufsize  = env->request_bufsize;
            client->response_bufsize = env->response_bufsize;
            client->event_state      = NA_EVENT_STATE_CLIENT_READ;
            client->req_cnt          = 0;
            client->res_cnt          = 0;
            na_event_switch(EV_A_ w, &client->c_watcher, cfd, EV_READ);
            return;
        }

    }
}

最後に書き出し完了していたらclientを初期化して、na_event_switchでまたREADフェーズに入っている。動的に確保したバッファーも解放したりはしてない。

ここまででneoagentの挙動は理解できた。コネクションプールとかクライアントプールっていったい何なの?とかソケットの扱いとか色々あるけど、とりあえず1人読書会はここまでにしておく。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1