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請求當然是它的核心功能。mongoose之worker_thread()函數
前面已經介紹過了mongoose的生產者過程,現在介紹下消費者過程。mongoose默認創建了10個worker_thread()線程來處理已接受的連接。worker_thread()函數原型如下:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.