//shpool must be locked. No memory is freed. static ngx_http_push_msg_t *ngx_http_push_get_oldest_message_locked(ngx_http_push_channel_t * channel) { ngx_queue_t *sentinel = &channel->message_queue->queue; if(ngx_queue_empty(sentinel)) { return NULL; } ngx_queue_t *qmsg = ngx_queue_head(sentinel); return ngx_queue_data(qmsg, ngx_http_push_msg_t, queue); }
static void ngx_http_limit_req2_expire(ngx_http_request_t *r, ngx_http_limit_req2_ctx_t *ctx, ngx_uint_t n) { ngx_int_t excess; ngx_time_t *tp; ngx_msec_t now; ngx_queue_t *q; ngx_msec_int_t ms; ngx_rbtree_node_t *node; ngx_http_limit_req2_node_t *lr; tp = ngx_timeofday(); now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); /* * n == 1 deletes one or two zero rate entries * n == 0 deletes oldest entry by force * and one or two zero rate entries */ while (n < 3) { if (ngx_queue_empty(&ctx->sh->queue)) { return; } q = ngx_queue_last(&ctx->sh->queue); lr = ngx_queue_data(q, ngx_http_limit_req2_node_t, queue); if (n++ != 0) { ms = (ngx_msec_int_t) (now - lr->last); ms = ngx_abs(ms); if (ms < 60000) { return; } excess = lr->excess - ctx->rate * ms / 1000; if (excess > 0) { return; } } ngx_queue_remove(q); node = (ngx_rbtree_node_t *) ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); } }
int main(void) { ngx_pool_t *pool; yahoo_guy_t *guy; ngx_queue_t *q; yahoo_t *yahoo; pool = ngx_create_pool(1024 * 10, NULL); int i; const ngx_str_t names[] = { ngx_string("rainx"), ngx_string("xiaozhe"), ngx_string("zhoujian") }; const int ids[] = {4611, 8322, 6111}; yahoo = ngx_palloc(pool, sizeof(yahoo_t)); ngx_queue_init(&yahoo->queue); for (i=0; i < 3; i++) { guy = (yahoo_guy_t *) ngx_palloc(pool, sizeof(yahoo_guy_t)); guy->id = ids[i]; guy->name = (u_char*) ngx_pstrdup(pool, (ngx_str_t*) &(names[i])); ngx_queue_init(&guy->queue); ngx_queue_insert_head(&yahoo->queue, &guy->queue); } for (q = ngx_queue_last(&yahoo->queue); q != ngx_queue_sentinel(&yahoo->queue); q = ngx_queue_prev(q)) { guy = ngx_queue_data(q, yahoo_guy_t, queue); printf("No, %d guy in yahoo is %s\n", guy->id, guy->name); } ngx_queue_sort(&yahoo->queue, yahoo_no_cmp); printf("Sorting...\n"); for (q = ngx_queue_prev(&yahoo->queue); q != ngx_queue_sentinel(&yahoo->queue); q = ngx_queue_last(q)) { guy = ngx_queue_data(q, yahoo_guy_t, queue); printf("No. %d guy in yahoo is %s\n", guy->id, guy->name); } ngx_destroy_pool(pool); return 0; }
static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data) { ngx_http_upstream_keepalive_peer_data_t *kp = data; ngx_http_upstream_keepalive_cache_t *item; ngx_int_t rc; ngx_queue_t *q, *cache; ngx_connection_t *c; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get keepalive peer"); /* ask balancer */ rc = kp->original_get_peer(pc, kp->data); if (rc != NGX_OK) { return rc; } /* search cache for suitable connection */ cache = &kp->conf->cache; for (q = ngx_queue_head(cache); q != ngx_queue_sentinel(cache); q = ngx_queue_next(q)) { item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue); c = item->connection; if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr, item->socklen, pc->socklen) == 0) { ngx_queue_remove(q); ngx_queue_insert_head(&kp->conf->free, q); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get keepalive peer: using connection %p", c); c->idle = 0; c->log = pc->log; c->read->log = pc->log; c->write->log = pc->log; c->pool->log = pc->log; pc->connection = c; pc->cached = 1; return NGX_DONE; } } return NGX_OK; }
static ngx_int_t ngx_http_ip_blacklist_manager(void) { ngx_queue_t *node; ngx_queue_t *tmp; ngx_http_ip_blacklist_tree_t *blacklist; ngx_http_ip_blacklist_t *bn; blacklist = ngx_http_ip_blacklist_shm_zone->data; ngx_shmtx_lock(&blacklist->shpool->mutex); if (ngx_queue_empty(&blacklist->garbage)) { goto out; } for (node = ngx_queue_head(&blacklist->garbage); node != ngx_queue_sentinel(&blacklist->garbage); node = ngx_queue_next(node)) { bn = ngx_queue_data(node, ngx_http_ip_blacklist_t, queue); if (bn->blacklist) { if (bn->timeout <= ngx_time()) { if (bn->ref != 0) { /* wait for request cleanup handler to delete this */ bn->timed = 1; bn->blacklist = 0; goto out; } /* blacklist timed out */ tmp = node; node = ngx_queue_prev(node); ngx_rbtree_delete(&blacklist->blacklist, &bn->node); ngx_queue_remove(tmp); ngx_slab_free_locked(blacklist->shpool, bn); } } else { if (bn->ref == 0) { tmp = node; node = ngx_queue_prev(node); ngx_rbtree_delete(&blacklist->blacklist, &bn->node); ngx_queue_remove(tmp); ngx_slab_free_locked(blacklist->shpool, bn); } else { /* wait for request cleanup handler to delete this */ bn->timed = 1; } } } out: ngx_shmtx_unlock(&blacklist->shpool->mutex); return NGX_OK; }
static int ngx_tcp_lua_shdict_expire(ngx_tcp_lua_shdict_ctx_t *ctx, ngx_uint_t n) { ngx_time_t *tp; uint64_t now; ngx_queue_t *q; int64_t ms; ngx_rbtree_node_t *node; ngx_tcp_lua_shdict_node_t *sd; int freed = 0; tp = ngx_timeofday(); now = (uint64_t) tp->sec * 1000 + tp->msec; /* * n == 1 deletes one or two expired entries * n == 0 deletes oldest entry by force * and one or two zero rate entries */ while (n < 3) { if (ngx_queue_empty(&ctx->sh->queue)) { return freed; } q = ngx_queue_last(&ctx->sh->queue); sd = ngx_queue_data(q, ngx_tcp_lua_shdict_node_t, queue); if (n++ != 0) { if (sd->expires == 0) { return freed; } ms = sd->expires - now; if (ms > 0) { return freed; } } ngx_queue_remove(q); node = (ngx_rbtree_node_t *) ((u_char *) sd - offsetof(ngx_rbtree_node_t, color)); ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); freed++; } return freed; }
static ngx_int_t ngx_http_push_stream_send_response_channels_info_detailed(ngx_http_request_t *r, ngx_http_push_stream_requested_channel_t *requested_channels) { ngx_str_t *text; ngx_queue_t queue_channel_info; ngx_http_push_stream_content_subtype_t *subtype = ngx_http_push_stream_match_channel_info_format_and_content_type(r, 1); ngx_http_push_stream_channel_info_t *channel_info; ngx_http_push_stream_requested_channel_t *requested_channel; ngx_queue_t *q; ngx_uint_t qtd_channels = 0; ngx_queue_init(&queue_channel_info); for (q = ngx_queue_head(&requested_channels->queue); q != ngx_queue_sentinel(&requested_channels->queue); q = ngx_queue_next(q)) { requested_channel = ngx_queue_data(q, ngx_http_push_stream_requested_channel_t, queue); if ((requested_channel->channel != NULL) && ((channel_info = ngx_pcalloc(r->pool, sizeof(ngx_http_push_stream_channel_info_t))) != NULL)) { channel_info->id.data = requested_channel->channel->id.data; channel_info->id.len = requested_channel->channel->id.len; channel_info->published_messages = requested_channel->channel->last_message_id; channel_info->stored_messages = requested_channel->channel->stored_messages; channel_info->subscribers = requested_channel->channel->subscribers; ngx_queue_insert_tail(&queue_channel_info, &channel_info->queue); qtd_channels++; } } if (qtd_channels == 0) { return ngx_http_push_stream_send_only_header_response(r, NGX_HTTP_NOT_FOUND, NULL); } if (qtd_channels == 1) { channel_info = ngx_queue_data(ngx_queue_head(&queue_channel_info), ngx_http_push_stream_channel_info_t, queue); text = ngx_http_push_stream_channel_info_formatted(r->pool, subtype->format_item, &channel_info->id, channel_info->published_messages, channel_info->stored_messages, channel_info->subscribers); if (text == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } return ngx_http_push_stream_send_response(r, text, subtype->content_type, NGX_HTTP_OK); } return ngx_http_push_stream_send_response_channels_info(r, &queue_channel_info); }
static void ngx_http_ip_behavior_expire(ngx_http_ip_behavior_ctx_t *ctx, ngx_uint_t force) { ngx_time_t *tp; ngx_msec_t now; ngx_msec_int_t ms; ngx_queue_t *q; ngx_rbtree_node_t *node; ngx_http_ip_behavior_node_t *ibn; ngx_uint_t i; ngx_uint_t n; tp = ngx_timeofday(); now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); /* delete at most 2 oldest nodes when a new request comes in * or * delete 10 oldest nodes ignoring the expires when "force" is set to 1 */ if (force) { n = 10; } else { n = 2; } for (i = 0; i < n; i++) { if (ngx_queue_empty(&ctx->sh->queue)) { return; } q = ngx_queue_last(&ctx->sh->queue); ibn = ngx_queue_data(q, ngx_http_ip_behavior_node_t, queue); if (!force) { ms = (ngx_msec_int_t) (now - ibn->last); ms = ngx_abs(ms); if (ms < ctx->sample_cycle) { /* the oldest is not expired, no need to check prev nodes */ return; } } ngx_queue_remove(q); node = (ngx_rbtree_node_t *) ((u_char *) ibn - offsetof(ngx_rbtree_node_t, color)); ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); } }
void print_queue(ngx_queue_t *h) { ngx_queue_t *t; for( t=ngx_queue_head(h); t != ngx_queue_sentinel(h); t = ngx_queue_next(t)) { ngx_qTest_t *tmp = ngx_queue_data(t, ngx_qTest_t, link); printf("Key:%d, name:%s\n", tmp->key, tmp->name); } }
static void uv__udp_run_pending(uv_udp_t* handle) { uv_udp_send_t* req; ngx_queue_t* q; struct msghdr h; ssize_t size; while (!ngx_queue_empty(&handle->write_queue)) { q = ngx_queue_head(&handle->write_queue); assert(q != NULL); req = ngx_queue_data(q, uv_udp_send_t, queue); assert(req != NULL); memset(&h, 0, sizeof h); h.msg_name = &req->addr; h.msg_namelen = (req->addr.sin6_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); h.msg_iov = (struct iovec*)req->bufs; h.msg_iovlen = req->bufcnt; do { size = sendmsg(handle->io_watcher.fd, &h, 0); } while (size == -1 && errno == EINTR); /* TODO try to write once or twice more in the * hope that the socket becomes readable again? */ if (size == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) break; req->status = (size == -1 ? -errno : size); #ifndef NDEBUG /* Sanity check. */ if (size != -1) { ssize_t nbytes; int i; for (nbytes = i = 0; i < req->bufcnt; i++) nbytes += req->bufs[i].len; assert(size == nbytes); } #endif /* Sending a datagram is an atomic operation: either all data * is written or nothing is (and EMSGSIZE is raised). That is * why we don't handle partial writes. Just pop the request * off the write queue and onto the completed queue, done. */ ngx_queue_remove(&req->queue); ngx_queue_insert_tail(&handle->write_completed_queue, &req->queue); } }
static uv_process_t* uv__process_find(uv_loop_t* loop, int pid) { uv_process_t* handle; ngx_queue_t* h; ngx_queue_t* q; h = uv__process_queue(loop, pid); ngx_queue_foreach(q, h) { handle = ngx_queue_data(q, uv_process_t, queue); if (handle->pid == pid) return handle; }
static void ngx_open_file_cache_cleanup(void *data) { ngx_open_file_cache_t *cache = data; ngx_queue_t *q; ngx_cached_open_file_t *file; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "open file cache cleanup"); for ( ;; ) { if (ngx_queue_empty(&cache->expire_queue)) { break; } q = ngx_queue_last(&cache->expire_queue); file = ngx_queue_data(q, ngx_cached_open_file_t, queue); ngx_queue_remove(q); ngx_rbtree_delete(&cache->rbtree, &file->node); cache->current--; ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "delete cached open file: %s", file->name); if (!file->err && !file->is_dir) { file->close = 1; file->count = 0; ngx_close_cached_file(cache, file, 0, ngx_cycle->log); } else { ngx_free(file->name); ngx_free(file); } } if (cache->current) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%ui items still leave in open file cache", cache->current); } if (cache->rbtree.root != cache->rbtree.sentinel) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "rbtree still is not empty in open file cache"); } }
ngx_int_t ngx_postgres_keepalive_get_peer_single(ngx_peer_connection_t *pc, ngx_postgres_upstream_peer_data_t *pgp, ngx_postgres_upstream_srv_conf_t *pgscf) { ngx_postgres_keepalive_cache_t *item; ngx_queue_t *q; ngx_connection_t *c; dd("entering"); if (!ngx_queue_empty(&pgscf->cache)) { dd("non-empty queue"); q = ngx_queue_head(&pgscf->cache); ngx_queue_remove(q); item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t, queue); c = item->connection; ngx_queue_insert_head(&pgscf->free, q); c->idle = 0; c->log = pc->log; #if defined(nginx_version) && (nginx_version >= 1001004) c->pool->log = pc->log; #endif c->read->log = pc->log; c->write->log = pc->log; pgp->name.data = item->name.data; pgp->name.len = item->name.len; pgp->sockaddr = item->sockaddr; pgp->pgconn = item->pgconn; pc->connection = c; pc->cached = 1; pc->name = &pgp->name; pc->sockaddr = &pgp->sockaddr; pc->socklen = item->socklen; dd("returning NGX_DONE"); return NGX_DONE; } dd("returning NGX_DECLINED"); return NGX_DECLINED; }
static max_connections_peer_data_t * queue_oldest (max_connections_srv_conf_t *maxconn_cf) { if(ngx_queue_empty(&maxconn_cf->waiting_requests)) return NULL; ngx_queue_t *last = ngx_queue_last(&maxconn_cf->waiting_requests); max_connections_peer_data_t *peer_data = ngx_queue_data(last, max_connections_peer_data_t, queue); return peer_data; }
int ngx_shmap_flush_expired(ngx_shm_zone_t* zone, int attempts) { ngx_queue_t *q, *prev; ngx_shmap_node_t *sd; ngx_shmap_ctx_t *ctx; ngx_time_t *tp; int freed = 0; ngx_rbtree_node_t *node; uint64_t now; assert(zone != NULL); ctx = zone->data; ngx_shmtx_lock(&ctx->shpool->mutex); if (ngx_queue_empty(&ctx->sh->queue)) { return 0; } tp = ngx_timeofday(); now = (uint64_t) tp->sec * 1000 + tp->msec; q = ngx_queue_last(&ctx->sh->queue); while (q != ngx_queue_sentinel(&ctx->sh->queue)) { prev = ngx_queue_prev(q); sd = ngx_queue_data(q, ngx_shmap_node_t, queue); if (sd->expires != 0 && sd->expires <= now) { ngx_queue_remove(q); node = (ngx_rbtree_node_t *) ((u_char *) sd - offsetof(ngx_rbtree_node_t, color)); ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); freed++; if (attempts && freed == attempts) { break; } } q = prev; } ngx_shmtx_unlock(&ctx->shpool->mutex); return freed; }
void dump_queue_from_tail(ngx_queue_t *que) { ngx_queue_t *q = ngx_queue_last(que); printf("(0x%x: (0x%x, 0x%x)) <==> \n", que, que->prev, que->next); for (; q != ngx_queue_sentinel(que); q = ngx_queue_prev(q)) { my_point_queue_t *point = ngx_queue_data(q, my_point_queue_t, queue); printf("(0x%x: (%-2d, %-2d), 0x%x: (0x%x, 0x%x)) <==> \n", point, point->point.x, point->point.y, &point->queue, point->queue.prev, point->queue.next); } }
static void ngx_http_dynamic_redirect_exit_process(ngx_cycle_t *cycle) { ngx_queue_t* q; redis_connection* item; while (!ngx_queue_empty(&redis_connection_queue->queue)) { q = ngx_queue_head(&redis_connection_queue->queue); item = ngx_queue_data(q, redis_connection, queue); redisFree(item->redis_context); ngx_queue_remove(q); } }
static void uv__run_pending(uv_loop_t* loop) { ngx_queue_t* q; uv__io_t* w; while (!ngx_queue_empty(&loop->pending_queue)) { q = ngx_queue_head(&loop->pending_queue); ngx_queue_remove(q); ngx_queue_init(q); w = ngx_queue_data(q, uv__io_t, pending_queue); w->cb(loop, w, UV__POLLOUT); } }
static void ngx_btt_expire(ngx_event_t *ev) { #if 0 time_t now; ngx_uint_t i; ngx_queue_t *q; #endif ngx_btt_conf_t *bcf; #if 0 ngx_btt_torrent_t *t; #endif ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "btt expire"); bcf = ev->data; #if 0 if (!ngx_shmtx_trylock(&bcf->pool->mutex)) { goto done; } now = ngx_time(); for (i = 0; i < 2; i++) { if (ngx_queue_empty(&bcf->cache->queue)) { break; } q = ngx_queue_last(&bcf->cache->queue); code = ngx_queue_data(q, ngx_btt_torrent_t, queue); if (code->expire >= now) { break; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "lua cache expire node \"%V\"", &code->path); ngx_queue_remove(&code->queue); ngx_rbtree_delete(&bcf->cache->rbtree, &code->node); ngx_slab_free_locked(bcf->pool, code); } ngx_shmtx_unlock(&bcf->pool->mutex); done: #endif ngx_add_timer(&bcf->event, bcf->expire * 1000 / 10); }
ngx_int_t ngx_http_drizzle_keepalive_get_peer_multi(ngx_peer_connection_t *pc, ngx_http_upstream_drizzle_peer_data_t *dp, ngx_http_upstream_drizzle_srv_conf_t *dscf) { ngx_queue_t *q, *cache; ngx_http_drizzle_keepalive_cache_t *item; ngx_connection_t *c; /* search cache for suitable connection */ cache = &dscf->cache; for (q = ngx_queue_head(cache); q != ngx_queue_sentinel(cache); q = ngx_queue_next(q)) { item = ngx_queue_data(q, ngx_http_drizzle_keepalive_cache_t, queue); c = item->connection; /* XXX maybe we should take dbname and user into account * as well? */ if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr, item->socklen, pc->socklen) == 0) { ngx_queue_remove(q); ngx_queue_insert_head(&dscf->free, q); c->idle = 0; c->log = pc->log; c->read->log = pc->log; c->write->log = pc->log; pc->connection = c; pc->cached = 1; /* we do not need to resume dp->name here because * it already takes the right value in the * ngx_http_upstream_drizzle_get_peer function */ dp->drizzle_con = item->drizzle_con; dp->has_set_names = item->has_set_names; dp->used = item->used; return NGX_DONE; } } return NGX_DECLINED; }
static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, ngx_log_t *log) { time_t now; ngx_queue_t *q; ngx_cached_open_file_t *file; now = ngx_time(); /* * n == 1 deletes one or two inactive files * n == 0 deletes least recently used file by force * and one or two inactive files */ while (n < 3) { // 如果队列为空,则直接返回 if (ngx_queue_empty(&cache->expire_queue)) { return; } // 取出最后一个文件,也就是可能需要被超时的文件 // (因为尾部是最长时间没有操作的文件) q = ngx_queue_last(&cache->expire_queue); file = ngx_queue_data(q, ngx_cached_open_file_t, queue); // n是控制是强制超时,还是按inactive超时,后一个判断是判断是否超时 if (n++ != 0 && now - file->accessed <= cache->inactive) { return; } // 如果有超时的,或者需要强制超时,则开始从队列和红黑树中移除 ngx_queue_remove(q); ngx_rbtree_delete(&cache->rbtree, &file->node); cache->current--; ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "expire cached open file: %s", file->name); if (!file->err && !file->is_dir) { file->close = 1; // 关闭文件 ngx_close_cached_file(cache, file, 0, log); } else { ngx_free(file->name); ngx_free(file); } } }
ngx_int_t ngx_postgres_keepalive_get_peer_multi(ngx_peer_connection_t *pc, ngx_postgres_upstream_peer_data_t *pgp, ngx_postgres_upstream_srv_conf_t *pgscf) { ngx_postgres_keepalive_cache_t *item; ngx_queue_t *q, *cache; ngx_connection_t *c; dd("entering"); cache = &pgscf->cache; for (q = ngx_queue_head(cache); q != ngx_queue_sentinel(cache); q = ngx_queue_next(q)) { item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t, queue); c = item->connection; if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr, item->socklen, pc->socklen) == 0) { ngx_queue_remove(q); ngx_queue_insert_head(&pgscf->free, q); c->idle = 0; c->log = pc->log; #if defined(nginx_version) && (nginx_version >= 1001004) c->pool->log = pc->log; #endif c->read->log = pc->log; c->write->log = pc->log; pc->connection = c; pc->cached = 1; /* we do not need to resume the peer name * because we already take the right value outside */ pgp->pgconn = item->pgconn; dd("returning NGX_DONE"); return NGX_DONE; } } dd("returning NGX_DECLINED"); return NGX_DECLINED; }
static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, ngx_log_t *log) { time_t now; ngx_queue_t *q; ngx_cached_open_file_t *file; now = ngx_time(); /* * n == 1 deletes one or two inactive files * n == 0 deletes least recently used file by force * and one or two inactive files */ while (n < 3) { if (ngx_queue_empty(&cache->expire_queue)) { return; } q = ngx_queue_last(&cache->expire_queue); file = ngx_queue_data(q, ngx_cached_open_file_t, queue); if (n++ != 0 && now - file->accessed <= cache->inactive) { return; } ngx_queue_remove(q); ngx_rbtree_delete(&cache->rbtree, &file->node); cache->current--; ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "expire cached open file: %s", file->name); if (!file->err && !file->is_dir) { file->close = 1; ngx_close_cached_file(cache, file, 0, log); } else { ngx_free(file->name); ngx_free(file); } } }
static void ngx_http_limit_traffic_rate_filter_cleanup(void *data) { ngx_http_limit_traffic_rate_filter_cleanup_t *lircln = data; ngx_slab_pool_t *shpool; ngx_rbtree_node_t *node; ngx_http_limit_traffic_rate_filter_ctx_t *ctx; ngx_http_limit_traffic_rate_filter_node_t *lir; ctx = lircln->shm_zone->data; shpool = (ngx_slab_pool_t *) lircln->shm_zone->shm.addr; node = lircln->node; lir = (ngx_http_limit_traffic_rate_filter_node_t *) &node->color; ngx_shmtx_lock(&shpool->mutex); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lircln->shm_zone->shm.log, 0, "limit traffic rate cleanup: %08XD %d", node->key, lir->conn); lir->conn--; if (lir->conn == 0) { ngx_queue_t *p = lir->rq_top.next; ngx_queue_t *c; ngx_http_limit_traffic_rate_filter_request_queue_t * tr; for(; p; ){ c = p; p = ngx_queue_next(p); if(ngx_queue_next(c) && ngx_queue_prev(c)){ ngx_queue_remove(c); } tr = ngx_queue_data(c, ngx_http_limit_traffic_rate_filter_request_queue_t, rq); if (!tr->r){ ngx_slab_free_locked(shpool, tr); } if(ngx_queue_last(&lir->rq_top) == p){ break; } } ngx_rbtree_delete(ctx->rbtree, node); ngx_slab_free_locked(shpool, node); } ngx_shmtx_unlock(&shpool->mutex); }
static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q, u_char *name) { u_char *p; size_t len; ngx_path_t *path; ngx_http_file_cache_node_t *fcn; fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); if (fcn->exists) { cache->sh->size -= fcn->fs_size; path = cache->path; p = name + path->name.len + 1 + path->len; p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); p = ngx_hex_dump(p, fcn->key, len); *p = '\0'; fcn->count++; fcn->deleting = 1; ngx_shmtx_unlock(&cache->shpool->mutex); len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; ngx_create_hashed_filename(path, name, len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire: \"%s\"", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", name); } ngx_shmtx_lock(&cache->shpool->mutex); fcn->count--; fcn->deleting = 0; } if (fcn->count == 0) { ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); } }
static void ngx_http_push_stream_publisher_body_handler(ngx_http_request_t *r) { ngx_str_t *event_id, *event_type; ngx_http_push_stream_module_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module); ngx_http_push_stream_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module); ngx_buf_t *buf = NULL; ngx_http_push_stream_channel_t *channel; ngx_http_push_stream_requested_channel_t *requested_channel; ngx_queue_t *cur = &ctx->requested_channels->queue; // check if body message wasn't empty if (r->headers_in.content_length_n <= 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: Post request was sent with no message"); ngx_http_push_stream_send_only_header_response(r, NGX_HTTP_BAD_REQUEST, &NGX_HTTP_PUSH_STREAM_EMPTY_POST_REQUEST_MESSAGE); return; } // get and check if has access to request body NGX_HTTP_PUSH_STREAM_CHECK_AND_FINALIZE_REQUEST_ON_ERROR(r->request_body->bufs, NULL, r, "push stream module: unexpected publisher message request body buffer location. please report this to the push stream module developers."); // copy request body to a memory buffer,将request body拷贝到一个buffer中 buf = ngx_http_push_stream_read_request_body_to_buffer(r); NGX_HTTP_PUSH_STREAM_CHECK_AND_FINALIZE_REQUEST_ON_ERROR(buf, NULL, r, "push stream module: cannot allocate memory for read the message"); event_id = ngx_http_push_stream_get_header(r, &NGX_HTTP_PUSH_STREAM_HEADER_EVENT_ID); event_type = ngx_http_push_stream_get_header(r, &NGX_HTTP_PUSH_STREAM_HEADER_EVENT_TYPE); while ((cur = ngx_queue_next(cur)) != &ctx->requested_channels->queue) { requested_channel = ngx_queue_data(cur, ngx_http_push_stream_requested_channel_t, queue); channel = ngx_http_push_stream_add_msg_to_channel(r, requested_channel->id, buf->pos, ngx_buf_size(buf), event_id, event_type, r->pool); if (channel == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } } if (cf->channel_info_on_publish) { ngx_http_push_stream_send_response_channels_info_detailed(r, ctx->requested_channels); } else { ngx_http_push_stream_send_only_header_response(r, NGX_HTTP_OK, NULL); } ngx_http_finalize_request(r, NGX_OK); return; }
static void ngx_http_push_stream_publisher_delete_handler(ngx_http_request_t *r) { ngx_http_push_stream_main_conf_t *mcf = ngx_http_get_module_main_conf(r, ngx_http_push_stream_module); ngx_http_push_stream_module_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module); ngx_buf_t *buf = NULL; u_char *text = mcf->channel_deleted_message_text.data; size_t len = mcf->channel_deleted_message_text.len; ngx_uint_t qtd_channels = 0; ngx_int_t rc; ngx_http_push_stream_requested_channel_t *requested_channel; ngx_queue_t *q; if (r->headers_in.content_length_n > 0) { // get and check if has access to request body NGX_HTTP_PUSH_STREAM_CHECK_AND_FINALIZE_REQUEST_ON_ERROR(r->request_body->bufs, NULL, r, "push stream module: unexpected publisher message request body buffer location. please report this to the push stream module developers."); buf = ngx_http_push_stream_read_request_body_to_buffer(r); NGX_HTTP_PUSH_STREAM_CHECK_AND_FINALIZE_REQUEST_ON_ERROR(buf, NULL, r, "push stream module: cannot allocate memory for read the message"); text = buf->pos; len = ngx_buf_size(buf); } for (q = ngx_queue_head(&ctx->requested_channels->queue); q != ngx_queue_sentinel(&ctx->requested_channels->queue); q = ngx_queue_next(q)) { requested_channel = ngx_queue_data(q, ngx_http_push_stream_requested_channel_t, queue); rc = ngx_http_push_stream_delete_channel(mcf, requested_channel->channel, text, len, r->pool); if (rc == -1) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: error while deleting channel '%V'", &requested_channel->channel->id); ngx_http_push_stream_send_only_header_response_and_finalize(r, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL); return; } if (rc > 0) { qtd_channels++; } } if (qtd_channels == 0) { ngx_http_push_stream_send_only_header_response_and_finalize(r, NGX_HTTP_NOT_FOUND, NULL); } else { ngx_http_push_stream_send_only_header_response_and_finalize(r, NGX_HTTP_OK, &NGX_HTTP_PUSH_STREAM_CHANNEL_DELETED); } }
static ngx_int_t ngx_http_ip_blacklist_flush_handler(ngx_http_request_t *r) { ngx_http_ip_blacklist_main_conf_t *imcf; ngx_http_ip_blacklist_tree_t *blacklist; ngx_http_ip_blacklist_t *bn; ngx_queue_t *node; ngx_queue_t *tmp; imcf = ngx_http_get_module_main_conf(r, ngx_http_ip_blacklist_module); if (!imcf->enabled) { return NGX_HTTP_CLOSE; } blacklist = ngx_http_ip_blacklist_shm_zone->data; ngx_shmtx_lock(&blacklist->shpool->mutex); if (ngx_queue_empty(&blacklist->garbage)) { ngx_shmtx_unlock(&blacklist->shpool->mutex); return NGX_HTTP_CLOSE; } for (node = ngx_queue_head(&blacklist->garbage); node != ngx_queue_sentinel(&blacklist->garbage); node = ngx_queue_next(node)) { bn = ngx_queue_data(node, ngx_http_ip_blacklist_t, queue); if (bn->ref != 0) { /* force node to time out */ bn->timed = 1; continue; } tmp = node; node = ngx_queue_prev(node); ngx_rbtree_delete(&blacklist->blacklist, &bn->node); ngx_queue_remove(tmp); ngx_slab_free_locked(blacklist->shpool, bn); } ngx_shmtx_unlock(&blacklist->shpool->mutex); return NGX_HTTP_CLOSE; }
static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) { time_t now; ngx_queue_t *q; ngx_resolver_node_t *rn; now = ngx_time(); for ( ;; ) { if (ngx_queue_empty(queue)) { return 0; } q = ngx_queue_last(queue); rn = ngx_queue_data(q, ngx_resolver_node_t, queue); if (now < rn->expire) { return rn->expire - now; } ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver resend \"%*s\" %p", (size_t) rn->nlen, rn->name, rn->waiting); ngx_queue_remove(q); if (rn->waiting) { if (ngx_resolver_send_query(r, rn) == NGX_OK) { rn->expire = now + r->resend_timeout; ngx_queue_insert_head(queue, &rn->queue); } continue; } ngx_rbtree_delete(tree, &rn->node); ngx_resolver_free_node(r, rn); } }
void pc_remove_listener(pc_client_t *client, const char *event, pc_event_cb cb) { uv_mutex_lock(&client->listener_mutex); ngx_queue_t *head = (ngx_queue_t *)pc_map_get(client->listeners, event); if(head == NULL) { return; } ngx_queue_t *item = NULL; pc_listener_t *listener = NULL; ngx_queue_foreach(item, head) { listener = ngx_queue_data(item, pc_listener_t, queue); if(listener->cb == cb) { ngx_queue_remove(item); pc_listener_destroy(listener); break; } }