mongoose之worker_thread()函數

前面已經介紹過了mongoose的生產者過程,現在介紹下消費者過程。mongoose默認創建了10個worker_thread()線程來處理已接受的連接。worker_thread()函數原型如下:
static void worker_thread(struct mg_context *ctx) 
{
  struct mg_connection *conn;
  int buf_size = atoi(ctx->config[MAX_REQUEST_SIZE]);

  conn = (struct mg_connection *) calloc(1, sizeof(*conn) + buf_size);
  if (conn == NULL) 
  {
    cry(fc(ctx), "%s", "Cannot create new connection struct, OOM");
    return;
  }
  conn->buf_size = buf_size;
  conn->buf = (char *) (conn + 1);

  // Call consume_socket() even when ctx->stop_flag > 0, to let it signal
  // sq_empty condvar to wake up the master waiting in produce_socket()
  while (consume_socket(ctx, &conn->client)) 
  {
    conn->birth_time = time(NULL);
    conn->ctx = ctx;

    // Fill in IP, port info early so even if SSL setup below fails,
    // error handler would have the corresponding info.
    // Thanks to Johannes Winkelmann for the patch.
    // TODO(lsm): Fix IPv6 case
    conn->request_info.remote_port = ntohs(conn->client.rsa.sin.sin_port);
    memcpy(&conn->request_info.remote_ip,
           &conn->client.rsa.sin.sin_addr.s_addr, 4);
    conn->request_info.remote_ip = ntohl(conn->request_info.remote_ip);
    conn->request_info.is_ssl = conn->client.is_ssl;

    if (!conn->client.is_ssl ||
        (conn->client.is_ssl && sslize(conn, SSL_accept))) 
    {
      process_new_connection(conn);
    }

    close_connection(conn);
  }
  free(conn);

  // Signal master that we're done with connection and exiting
  (void) pthread_mutex_lock(&ctx->mutex);
  ctx->num_threads--;
  (void) pthread_cond_signal(&ctx->cond);
  assert(ctx->num_threads >= 0);
  (void) pthread_mutex_unlock(&ctx->mutex);

  DEBUG_TRACE(("exiting"));
}
先創建了一個mg_connection類型的結構體變量,然後利用該變量從連接隊列尾部取出一個連接來處理。若隊列爲空的話一直等待直到被告知有連接準備好被處理。取出連接後用一些變量填充改結構體,然後就進入了主題:處理新連接。mongoose調用process_new_connection()函數來處理一個新連接。該函數也是mongoose最關鍵的函數之一。process_new_connection流程如下:初始化變量->讀取請求->解析http請求。作爲一個web服務器,解析http請求當然是它的核心功能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章