static void ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q) { u_char *name; size_t len; ngx_queue_t *x, tail; ngx_http_location_queue_t *lq, *lx; if (q == ngx_queue_last(locations)) { return; } lq = (ngx_http_location_queue_t *) q; if (lq->inclusive == NULL) { ngx_http_create_locations_list(locations, ngx_queue_next(q)); return; } len = lq->name->len; name = lq->name->data; for (x = ngx_queue_next(q); x != ngx_queue_sentinel(locations); x = ngx_queue_next(x)) { lx = (ngx_http_location_queue_t *) x; if (len > lx->name->len || (ngx_strncmp(name, lx->name->data, len) != 0)) { break; } } q = ngx_queue_next(q); if (q == x) { ngx_http_create_locations_list(locations, x); return; } ngx_queue_split(locations, q, &tail); ngx_queue_add(&lq->list, &tail); if (x == ngx_queue_sentinel(locations)) { ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list)); return; } ngx_queue_split(&lq->list, x, &tail); ngx_queue_add(locations, &tail); ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list)); ngx_http_create_locations_list(locations, x); }
void uv__cf_loop_cb(void* arg) { uv_loop_t* loop; ngx_queue_t* item; ngx_queue_t split_head; uv__cf_loop_signal_t* s; loop = arg; uv_mutex_lock(&loop->cf_mutex); ngx_queue_init(&split_head); if (!ngx_queue_empty(&loop->cf_signals)) { ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals); ngx_queue_split(&loop->cf_signals, split_pos, &split_head); } uv_mutex_unlock(&loop->cf_mutex); while (!ngx_queue_empty(&split_head)) { item = ngx_queue_head(&split_head); s = ngx_queue_data(item, uv__cf_loop_signal_t, member); s->cb(s->arg); ngx_queue_remove(item); free(s); } }
static void uv__cf_loop_cb(void* arg) { uv_loop_t* loop; ngx_queue_t* item; ngx_queue_t split_head; uv__cf_loop_signal_t* s; loop = arg; uv_mutex_lock(&loop->cf_mutex); ngx_queue_init(&split_head); if (!ngx_queue_empty(&loop->cf_signals)) { ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals); ngx_queue_split(&loop->cf_signals, split_pos, &split_head); } uv_mutex_unlock(&loop->cf_mutex); while (!ngx_queue_empty(&split_head)) { item = ngx_queue_head(&split_head); s = ngx_queue_data(item, uv__cf_loop_signal_t, member); /* This was a termination signal */ if (s->cb == NULL) CFRunLoopStop(loop->cf_loop); else s->cb(s->arg); ngx_queue_remove(item); free(s); } }
static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf) { ngx_uint_t n; ngx_queue_t *q, *locations, *named, tail; ngx_http_core_loc_conf_t *clcf; ngx_http_location_queue_t *lq; ngx_http_core_loc_conf_t **clcfp; #if (NGX_PCRE) ngx_uint_t r; ngx_queue_t *regex; #endif locations = pclcf->locations; if (locations == NULL) { return NGX_OK; } ngx_queue_sort(locations, ngx_http_cmp_locations); named = NULL; n = 0; #if (NGX_PCRE) regex = NULL; r = 0; #endif for (q = ngx_queue_head(locations); q != ngx_queue_sentinel(locations); q = ngx_queue_next(q)) { lq = (ngx_http_location_queue_t *) q; clcf = lq->exact ? lq->exact : lq->inclusive; if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) { return NGX_ERROR; } #if (NGX_PCRE) if (clcf->regex) { r++; if (regex == NULL) { regex = q; } continue; } #endif if (clcf->named) { n++; if (named == NULL) { named = q; } continue; } if (clcf->noname) { break; } } if (q != ngx_queue_sentinel(locations)) { ngx_queue_split(locations, q, &tail); } if (named) { clcfp = ngx_palloc(cf->pool, (n + 1) * sizeof(ngx_http_core_loc_conf_t **)); if (clcfp == NULL) { return NGX_ERROR; } cscf->named_locations = clcfp; for (q = named; q != ngx_queue_sentinel(locations); q = ngx_queue_next(q)) { lq = (ngx_http_location_queue_t *) q; *(clcfp++) = lq->exact; } *clcfp = NULL; ngx_queue_split(locations, named, &tail); } #if (NGX_PCRE) if (regex) { clcfp = ngx_palloc(cf->pool, (r + 1) * sizeof(ngx_http_core_loc_conf_t **)); if (clcfp == NULL) { return NGX_ERROR; } pclcf->regex_locations = clcfp; for (q = regex; q != ngx_queue_sentinel(locations); q = ngx_queue_next(q)) { lq = (ngx_http_location_queue_t *) q; *(clcfp++) = lq->exact; } *clcfp = NULL; ngx_queue_split(locations, regex, &tail); } #endif return NGX_OK; }
static ngx_http_location_tree_node_t * ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations, size_t prefix) { size_t len; ngx_queue_t *q, tail; ngx_http_location_queue_t *lq; ngx_http_location_tree_node_t *node; q = ngx_queue_middle(locations); lq = (ngx_http_location_queue_t *) q; len = lq->name->len - prefix; node = ngx_palloc(cf->pool, offsetof(ngx_http_location_tree_node_t, name) + len); if (node == NULL) { return NULL; } node->left = NULL; node->right = NULL; node->tree = NULL; node->exact = lq->exact; node->inclusive = lq->inclusive; node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect) || (lq->inclusive && lq->inclusive->auto_redirect)); node->len = (u_char) len; ngx_memcpy(node->name, &lq->name->data[prefix], len); ngx_queue_split(locations, q, &tail); if (ngx_queue_empty(locations)) { /* * ngx_queue_split() insures that if left part is empty, * then right one is empty too */ goto inclusive; } node->left = ngx_http_create_locations_tree(cf, locations, prefix); if (node->left == NULL) { return NULL; } ngx_queue_remove(q); if (ngx_queue_empty(&tail)) { goto inclusive; } node->right = ngx_http_create_locations_tree(cf, &tail, prefix); if (node->right == NULL) { return NULL; } inclusive: if (ngx_queue_empty(&lq->list)) { return node; } node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len); if (node->tree == NULL) { return NULL; } return node; }