//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);
    }
}
Пример #3
0
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;
}
Пример #5
0
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);
}
Пример #8
0
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);
    }
}
Пример #9
0
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);
    }
}
Пример #10
0
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);
  }
}
Пример #11
0
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");

    }
}
Пример #13
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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);
    }
}
Пример #18
0
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);
  }
}
Пример #19
0
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);
        }
    }
}
Пример #22
0
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;
}
Пример #23
0
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);
}
Пример #25
0
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);
    }
}
Пример #28
0
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;
}
Пример #29
0
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);
    }
}
Пример #30
0
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;
    }
  }