LoginSignup
14
16

More than 5 years have passed since last update.

nginx ソースコードリーディング 1-2

Last updated at Posted at 2012-03-14

今回読むところ

  • nginx-1.1.16
  • core/nginx.c:200 mainから呼ばれるos/unix/ngx_process_cycle.c:295 ngx_single_process_cycleの中身。

その前に

GNU GLOBALを使おう。

$ brew install global
$ cd nginx-1.1.16
$ git init
$ gtags -v
$ cat .gitignore
GPATH
GRTAGS
GTAGS
Makefile
objs/

Emacsの例。

init-tags.el
(autoload 'gtags-mode "gtags" "" t)
(setq gtags-mode-hook
      '(lambda ()
         (local-set-key "\M-t" 'gtags-find-tag)
         (local-set-key "\M-r" 'gtags-find-rtag)
         (local-set-key "\M-s" 'gtags-find-symbol)
         (local-set-key "\C-t" 'gtags-pop-stack)))

(add-hook 'c-mode-common-hook
          '(lambda()
             (gtags-mode 1)
             (gtags-make-complete-list)))

void ngx_single_process_cycle(ngx_cycle_t *cycle)

cycleの定義

ngx_core.h
typedef struct ngx_cycle_s       ngx_cycle_t;
ngx_core.h
struct ngx_cycle_s {
    void                  ****conf_ctx;
    ngx_pool_t               *pool;

    ngx_log_t                *log;
    ngx_log_t                 new_log;

    ngx_connection_t        **files;
    ngx_connection_t         *free_connections;
    ngx_uint_t                free_connection_n;

    ngx_queue_t               reusable_connections_queue;

    ngx_array_t               listening;
    ngx_array_t               pathes;
    ngx_list_t                open_files;
    ngx_list_t                shared_memory;

    ngx_uint_t                connection_n;
    ngx_uint_t                files_n;

    ngx_connection_t         *connections;
    ngx_event_t              *read_events;
    ngx_event_t              *write_events;

    ngx_cycle_t              *old_cycle;

    ngx_str_t                 conf_file;
    ngx_str_t                 conf_param;
    ngx_str_t                 conf_prefix;
    ngx_str_t                 prefix;
    ngx_str_t                 lock_file;
    ngx_str_t                 hostname;
};

処理の流れ

  1. モジュール初期化
  2. メインループ突入
    1. イベント処理
    2. 終了条件チェック
    3. 再初期化チェック
    4. ログの再オープン

イベント処理

ngx_event.c
void ngx_process_events_and_timers(ngx_cycle_t *cycle)
  1. タイムアウト設定
  2. イベント監視
  3. イベント処理
ngx_event.c
(void) ngx_process_events(cycle, timer, flags);

ngx_process_eventsがなにやってるか。

ngx_event.h
#define ngx_process_events   ngx_event_actions.process_events

// (snip)

typedef struct {
    ngx_int_t  (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    ngx_int_t  (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    ngx_int_t  (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    ngx_int_t  (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    ngx_int_t  (*add_conn)(ngx_connection_t *c);
    ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);

    ngx_int_t  (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
    ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
                   ngx_uint_t flags);

    ngx_int_t  (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
    void       (*done)(ngx_cycle_t *cycle);
} ngx_event_actions_t;

// (snip)

extern ngx_event_actions_t   ngx_event_actions;

この関数ポインタがつまったstruct(クラスっぽい感じのやつ)ngx_event_actionsを、各event APIモジュールが実装している。

以下、select(2)の例。初期化時に、上記のメンバに実装を設定する:

ngx_select_module.c
ngx_event_actions = ngx_select_module_ctx.actions;

んでもって、process_eventsの実装はこんな感じ:

ngx_select_module.c
static ngx_int_t
ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);

// (snip)

ngx_mutex_lock(ngx_posted_events_mutex);

nready = 0;

for (i = 0; i < nevents; i++) {
    ev = event_index[i];
    c = ev->data;
    found = 0;

    if (ev->write) {
        if (FD_ISSET(c->fd, &work_write_fd_set)) {
            found = 1;
            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "select write %d", c->fd);
        }

    } else {
        if (FD_ISSET(c->fd, &work_read_fd_set)) {
            found = 1;
            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "select read %d", c->fd);
        }
    }

    if (found) {
        ev->ready = 1;

        queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
                                               &ngx_posted_events);
        ngx_locked_post_event(ev, queue);

        nready++;
    }
}

ngx_mutex_unlock(ngx_posted_events_mutex);
// (snip)

以下略。

14
16
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
14
16