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请求当然是它的核心功能

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