Example #1
0
static void uv__write_callbacks(uv_tcp_t* tcp) {
  int callbacks_made = 0;
  ngx_queue_t* q;
  uv_write_t* req;

  while (!ngx_queue_empty(&tcp->write_completed_queue)) {
    /* Pop a req off write_completed_queue. */
    q = ngx_queue_head(&tcp->write_completed_queue);
    assert(q);
    req = ngx_queue_data(q, struct uv_write_s, queue);
    ngx_queue_remove(q);

    /* NOTE: call callback AFTER freeing the request data. */
    if (req->cb) {
      req->cb(req, 0);
    }

    callbacks_made++;
  }

  assert(ngx_queue_empty(&tcp->write_completed_queue));

  /* Write queue drained. */
  if (!uv_write_queue_head(tcp)) {
    uv__drain(tcp);
  }
}
Example #2
0
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);
  }
}
Example #3
0
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
  assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
  assert(0 != events);
  assert(w->fd >= 0);
  assert(w->fd < INT_MAX);

  w->pevents |= events;
  maybe_resize(loop, w->fd + 1);

#if !defined(__sun)
  /* The event ports backend needs to rearm all file descriptors on each and
   * every tick of the event loop but the other backends allow us to
   * short-circuit here if the event mask is unchanged.
   */
  if (w->events == w->pevents) {
    if (w->events == 0 && !ngx_queue_empty(&w->watcher_queue)) {
      ngx_queue_remove(&w->watcher_queue);
      ngx_queue_init(&w->watcher_queue);
    }
    return;
  }
#endif

  if (ngx_queue_empty(&w->watcher_queue))
    ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);

  if (loop->watchers[w->fd] == NULL) {
    loop->watchers[w->fd] = w;
    loop->nfds++;
  }
}
Example #4
0
void uv__stream_destroy(uv_stream_t* stream) {
  uv_write_t* req;
  ngx_queue_t* q;

  assert(stream->flags & UV_CLOSED);

  while (!ngx_queue_empty(&stream->write_queue)) {
    q = ngx_queue_head(&stream->write_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_write_t, queue);
    if (req->bufs != req->bufsml)
      free(req->bufs);

    if (req->cb) {
      uv__set_artificial_error(req->handle->loop, UV_EINTR);
      req->cb(req, -1);
    }
  }

  while (!ngx_queue_empty(&stream->write_completed_queue)) {
    q = ngx_queue_head(&stream->write_completed_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_write_t, queue);
    if (req->cb) {
      uv__set_sys_error(stream->loop, req->error);
      req->cb(req, req->error ? -1 : 0);
    }
  }
}
Example #5
0
static void uv__write_callbacks(uv_stream_t* stream) {
  int callbacks_made = 0;
  ngx_queue_t* q;
  uv_write_t* req;

  while (!ngx_queue_empty(&stream->write_completed_queue)) {
    /* Pop a req off write_completed_queue. */
    q = ngx_queue_head(&stream->write_completed_queue);
    assert(q);
    req = ngx_queue_data(q, struct uv_write_s, queue);
    ngx_queue_remove(q);

    /* NOTE: call callback AFTER freeing the request data. */
    if (req->cb) {
      uv__set_artificial_error(stream->loop, req->error);
      req->cb(req, req->error ? -1 : 0);
    }

    callbacks_made++;
  }

  assert(ngx_queue_empty(&stream->write_completed_queue));

  /* Write queue drained. */
  if (!uv_write_queue_head(stream)) {
    uv__drain(stream);
  }
}
Example #6
0
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);
  }
}
Example #7
0
void uv__stream_init(uv_loop_t* loop,
                     uv_stream_t* stream,
                     uv_handle_type type) {
  uv__handle_init(loop, (uv_handle_t*)stream, type);
  loop->counters.stream_init++;

  stream->alloc_cb = NULL;
  stream->close_cb = NULL;
  stream->connection_cb = NULL;
  stream->connect_req = NULL;
  stream->accepted_fd = -1;
  stream->fd = -1;
  stream->delayed_error = 0;
  stream->blocking = 0;
  ngx_queue_init(&stream->write_queue);
  ngx_queue_init(&stream->write_completed_queue);
  stream->write_queue_size = 0;

  ev_init(&stream->read_watcher, uv__stream_io);
  stream->read_watcher.data = stream;

  ev_init(&stream->write_watcher, uv__stream_io);
  stream->write_watcher.data = stream;

  assert(ngx_queue_empty(&stream->write_queue));
  assert(ngx_queue_empty(&stream->write_completed_queue));
  assert(stream->write_queue_size == 0);
}
Example #8
0
File: udp.c Project: nuxleus/libuv
static void uv__udp_sendmsg(EV_P_ ev_io* w, int revents) {
  uv_udp_t* handle;

  handle = container_of(w, uv_udp_t, write_watcher);
  assert(handle->type == UV_UDP);
  assert(revents & EV_WRITE);

  assert(!ngx_queue_empty(&handle->write_queue)
      || !ngx_queue_empty(&handle->write_completed_queue));

  /* Write out pending data first. */
  uv__udp_run_pending(handle);

  /* Drain 'request completed' queue. */
  uv__udp_run_completed(handle);

  if (!ngx_queue_empty(&handle->write_completed_queue)) {
    /* Schedule completion callbacks. */
    ev_feed_event(handle->loop->ev, &handle->write_watcher, EV_WRITE);
  }
  else if (ngx_queue_empty(&handle->write_queue)) {
    /* Pending queue and completion queue empty, stop watcher. */
    uv__udp_stop_write_watcher(handle);
  }
}
Example #9
0
File: udp.c Project: 76765357/node
static void uv__udp_sendmsg(uv_loop_t* loop,
                            uv__io_t* w,
                            unsigned int revents) {
  uv_udp_t* handle;

  handle = container_of(w, uv_udp_t, io_watcher);
  assert(handle->type == UV_UDP);
  assert(revents & UV__POLLOUT);

  assert(!ngx_queue_empty(&handle->write_queue)
      || !ngx_queue_empty(&handle->write_completed_queue));

  /* Write out pending data first. */
  uv__udp_run_pending(handle);

  /* Drain 'request completed' queue. */
  uv__udp_run_completed(handle);

  if (!ngx_queue_empty(&handle->write_completed_queue)) {
    /* Schedule completion callbacks. */
    uv__io_feed(handle->loop, &handle->io_watcher);
  }
  else if (ngx_queue_empty(&handle->write_queue)) {
    /* Pending queue and completion queue empty, stop watcher. */
    uv__io_stop(loop, &handle->io_watcher, UV__POLLOUT);

    if (!uv__io_active(&handle->io_watcher, UV__POLLIN))
      uv__handle_stop(handle);
  }
}
Example #10
0
static void uv__write_callbacks(uv_stream_t* stream) {
  uv_write_t* req;
  ngx_queue_t* q;

  while (!ngx_queue_empty(&stream->write_completed_queue)) {
    /* Pop a req off write_completed_queue. */
    q = ngx_queue_head(&stream->write_completed_queue);
    req = ngx_queue_data(q, uv_write_t, queue);
    ngx_queue_remove(q);
    uv__req_unregister(stream->loop, req);

    /* NOTE: call callback AFTER freeing the request data. */
    if (req->cb) {
      uv__set_sys_error(stream->loop, req->error);
      req->cb(req, req->error ? -1 : 0);
    }
  }

  assert(ngx_queue_empty(&stream->write_completed_queue));

  /* Write queue drained. */
  if (!uv_write_queue_head(stream)) {
    uv__drain(stream);
  }
}
Example #11
0
int uv_tcp_init(uv_tcp_t* tcp) {
  uv__handle_init((uv_handle_t*)tcp, UV_TCP);
  uv_counters()->tcp_init++;

  tcp->alloc_cb = NULL;
  tcp->connect_req = NULL;
  tcp->accepted_fd = -1;
  tcp->fd = -1;
  tcp->delayed_error = 0;
  ngx_queue_init(&tcp->write_queue);
  ngx_queue_init(&tcp->write_completed_queue);
  tcp->write_queue_size = 0;

  ev_init(&tcp->read_watcher, uv__tcp_io);
  tcp->read_watcher.data = tcp;

  ev_init(&tcp->write_watcher, uv__tcp_io);
  tcp->write_watcher.data = tcp;

  assert(ngx_queue_empty(&tcp->write_queue));
  assert(ngx_queue_empty(&tcp->write_completed_queue));
  assert(tcp->write_queue_size == 0);

  return 0;
}
/* Note: must be called with the mutex locked */
static ngx_buffer_cache_entry_t*
ngx_buffer_cache_free_oldest_entry(ngx_buffer_cache_sh_t *cache, uint32_t expiration)
{
	ngx_buffer_cache_entry_t* entry;

	// verify we have an entry to free
	if (ngx_queue_empty(&cache->used_queue))
	{
		return NULL;
	}

	// verify the entry is not locked
	entry = container_of(ngx_queue_head(&cache->used_queue), ngx_buffer_cache_entry_t, queue_node);
	if (entry->ref_count > 0 &&
		ngx_time() < entry->access_time + ENTRY_LOCK_EXPIRATION)
	{
		return NULL;
	}

	// make sure the entry is expired, if that is the requirement
	if (expiration && ngx_time() < (time_t)(entry->write_time + expiration))
	{
		return NULL;
	}
	
	// update the state
	entry->state = CES_FREE;

	// remove from rb tree
	ngx_rbtree_delete(&cache->rbtree, &entry->node);

	// move from used_queue to free_queue
	ngx_queue_remove(&entry->queue_node);
	ngx_queue_insert_tail(&cache->free_queue, &entry->queue_node);

	if (ngx_queue_empty(&cache->used_queue))
	{
		// queue is empty reset the read/write pointers
		cache->buffers_read = cache->buffers_end;
		cache->buffers_write = cache->buffers_end;
	}
	else
	{
		// update the read buffer pointer
		cache->buffers_read = entry->start_offset;
	}

	// update stats
	cache->stats.evicted++;
	cache->stats.evicted_bytes += entry->buffer_size;

	return entry;
}
Example #13
0
void uv__stream_destroy(uv_stream_t* stream) {
  uv_write_t* req;
  ngx_queue_t* q;

  assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
  assert(stream->flags & UV_CLOSED);

  if (stream->connect_req) {
    uv__req_unregister(stream->loop, stream->connect_req);
    uv__set_artificial_error(stream->loop, UV_ECANCELED);
    stream->connect_req->cb(stream->connect_req, -1);
    stream->connect_req = NULL;
  }

  while (!ngx_queue_empty(&stream->write_queue)) {
    q = ngx_queue_head(&stream->write_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_write_t, queue);
    uv__req_unregister(stream->loop, req);

    if (req->bufs != req->bufsml)
      free(req->bufs);

    if (req->cb) {
      uv__set_artificial_error(req->handle->loop, UV_ECANCELED);
      req->cb(req, -1);
    }
  }

  while (!ngx_queue_empty(&stream->write_completed_queue)) {
    q = ngx_queue_head(&stream->write_completed_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_write_t, queue);
    uv__req_unregister(stream->loop, req);

    if (req->cb) {
      uv__set_sys_error(stream->loop, req->error);
      req->cb(req, req->error ? -1 : 0);
    }
  }

  if (stream->shutdown_req) {
    uv__req_unregister(stream->loop, stream->shutdown_req);
    uv__set_artificial_error(stream->loop, UV_ECANCELED);
    stream->shutdown_req->cb(stream->shutdown_req, -1);
    stream->shutdown_req = NULL;
  }
}
void
ngx_postgres_keepalive_cleanup(void *data)
{
    ngx_postgres_upstream_srv_conf_t  *pgscf = data;
    ngx_postgres_keepalive_cache_t    *item;
    ngx_queue_t                       *q;

    dd("entering");

    /* ngx_queue_empty is broken when used on unitialized queue */
    if (pgscf->cache.prev == NULL) {
        dd("returning");
        return;
    }

    /* just to be on the safe-side */
    pgscf->max_cached = 0;

    while (!ngx_queue_empty(&pgscf->cache)) {
        q = ngx_queue_head(&pgscf->cache);
        ngx_queue_remove(q);

        item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t,
                              queue);

        dd("postgres: disconnecting %p", item->connection);

        ngx_postgres_upstream_free_connection(item->connection->log,
                                              item->connection,
                                              item->pgconn, pgscf);
    }

    dd("returning");
}
Example #15
0
File: udp.c Project: 76765357/node
void uv__udp_finish_close(uv_udp_t* handle) {
  uv_udp_send_t* req;
  ngx_queue_t* q;

  assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
  assert(handle->io_watcher.fd == -1);

  uv__udp_run_completed(handle);

  while (!ngx_queue_empty(&handle->write_queue)) {
    q = ngx_queue_head(&handle->write_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_udp_send_t, queue);
    uv__req_unregister(handle->loop, req);

    if (req->bufs != req->bufsml)
      free(req->bufs);
    req->bufs = NULL;

    if (req->send_cb) {
      uv__set_artificial_error(handle->loop, UV_ECANCELED);
      req->send_cb(req, -1);
    }
  }

  /* Now tear down the handle. */
  handle->flags = 0;
  handle->recv_cb = NULL;
  handle->alloc_cb = NULL;
  /* but _do not_ touch close_cb */
}
Example #16
0
File: loop.c Project: libtor/libuv
void uv__loop_delete(uv_loop_t* loop) {
  uv__signal_loop_cleanup(loop);
  uv__platform_loop_delete(loop);
  ev_loop_destroy(loop->ev);

  if (loop->async_pipefd[0] != -1) {
    close(loop->async_pipefd[0]);
    loop->async_pipefd[0] = -1;
  }

  if (loop->async_pipefd[1] != -1) {
    close(loop->async_pipefd[1]);
    loop->async_pipefd[1] = -1;
  }

  if (loop->emfile_fd != -1) {
    close(loop->emfile_fd);
    loop->emfile_fd = -1;
  }

  uv_mutex_lock(&loop->wq_mutex);
  assert(ngx_queue_empty(&loop->wq) && "thread pool work queue not empty!");
  uv_mutex_unlock(&loop->wq_mutex);
  uv_mutex_destroy(&loop->wq_mutex);
}
Example #17
0
File: udp.c Project: 76765357/node
static void uv__udp_run_completed(uv_udp_t* handle) {
  uv_udp_send_t* req;
  ngx_queue_t* q;

  while (!ngx_queue_empty(&handle->write_completed_queue)) {
    q = ngx_queue_head(&handle->write_completed_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_udp_send_t, queue);
    uv__req_unregister(handle->loop, req);

    if (req->bufs != req->bufsml)
      free(req->bufs);
    req->bufs = NULL;

    if (req->send_cb == NULL)
      continue;

    /* req->status >= 0 == bytes written
     * req->status <  0 == errno
     */
    if (req->status >= 0) {
      req->send_cb(req, 0);
    }
    else {
      uv__set_sys_error(handle->loop, -req->status);
      req->send_cb(req, -1);
    }
  }
}
static ngx_btt_peer_t *
ngx_btt_get_peer(ngx_btt_conf_t *bcf, ngx_btt_ctx_t *ctx, ngx_rbtree_t *tree,
    ngx_queue_t *queue)
{
    ngx_queue_t     *q;
    ngx_btt_peer_t  *p;

    p = NULL;

    if (!ngx_queue_empty(&bcf->btt->free_peers)) {
        q = ngx_queue_head(&bcf->btt->free_peers);
        ngx_queue_remove(q);

        p = ngx_queue_data(q, ngx_btt_peer_t, queue);
    }

    if (p == NULL) {
        p = ngx_slab_alloc_locked(bcf->pool, sizeof(ngx_btt_peer_t));
        if (p == NULL) {
            return NULL;
        }
    }

    /* TODO */

    ngx_memcpy(&p->connection_id, &ctx->connection_id,
               sizeof(ctx->connection_id));

    p->node.key = ngx_crc32_short((u_char *) &ctx->connection_id,
                                  sizeof(ctx->connection_id));
    ngx_rbtree_insert(tree, &p->node);
    ngx_queue_insert_head(queue, &p->queue);

    return p;
}
Example #19
0
File: udp.c Project: nuxleus/libuv
void uv__udp_finish_close(uv_udp_t* handle) {
  uv_udp_send_t* req;
  ngx_queue_t* q;

  assert(!ev_is_active(&handle->write_watcher));
  assert(!ev_is_active(&handle->read_watcher));
  assert(handle->fd == -1);

  uv__udp_run_completed(handle);

  while (!ngx_queue_empty(&handle->write_queue)) {
    q = ngx_queue_head(&handle->write_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_udp_send_t, queue);
    if (req->send_cb) {
      /* FIXME proper error code like UV_EABORTED */
      uv__set_artificial_error(handle->loop, UV_EINTR);
      req->send_cb(req, -1);
    }
  }

  /* Now tear down the handle. */
  handle->flags = 0;
  handle->recv_cb = NULL;
  handle->alloc_cb = NULL;
  /* but _do not_ touch close_cb */
}
ngx_int_t
ngx_http_drizzle_keepalive_get_peer_single(ngx_peer_connection_t *pc,
        ngx_http_upstream_drizzle_peer_data_t *dp,
        ngx_http_upstream_drizzle_srv_conf_t *dscf)
{
    ngx_http_drizzle_keepalive_cache_t      *item;
    ngx_queue_t                             *q;
    ngx_connection_t                        *c;

    if (! ngx_queue_empty(&dscf->cache)) {

        q = ngx_queue_head(&dscf->cache);
        ngx_queue_remove(q);

        item = ngx_queue_data(q, ngx_http_drizzle_keepalive_cache_t, queue);
        c = item->connection;

        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;

        dp->name = &item->name;
        dp->drizzle_con = item->drizzle_con;

        return NGX_DONE;
    }

    return NGX_DECLINED;
}
static void
ngx_http_req_status_expire(void *conf)
{
    ngx_queue_t                     *q;
    ngx_http_req_status_zone_t      *ctx = conf;
    ngx_http_req_status_node_t      *ssn;

    if (ngx_queue_empty(&ctx->sh->queue)) {
        return;
    }

    if (ctx->sh->expire_lock > ngx_time()){
        return;
    }

    q =  ngx_queue_last(&ctx->sh->queue);

    ssn = ngx_queue_data(q, ngx_http_req_status_node_t, queue);

    if (!ssn->data.requests || (ngx_current_msec > ssn->last_traffic_update &&
                ngx_current_msec - ssn->last_traffic_update >= 10 * 1000)){
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
                "req-status, release node, zone = \"%V\", key = \"%s\"",
                &ctx->shm_zone->shm.name, ssn->key);

        ngx_queue_remove(q);

        ngx_rbtree_delete(&ctx->sh->rbtree, &ssn->node);

        ngx_slab_free_locked(ctx->shpool, ssn);
    }
}
void
ngx_http_tfs_rc_server_expire(ngx_http_tfs_rc_ctx_t *ctx)
{
    ngx_queue_t             *q, *kp_q;
    ngx_rbtree_node_t       *node;
    ngx_http_tfs_rcs_info_t *rc_info_node;

    if (ngx_queue_empty(&ctx->sh->queue)) {
        return;
    }

    q = ngx_queue_last(&ctx->sh->queue);

    rc_info_node = ngx_queue_data(q, ngx_http_tfs_rcs_info_t, queue);
    kp_q = &rc_info_node->kp_queue;

    ngx_queue_remove(q);
    ngx_queue_remove(kp_q);

    node = (ngx_rbtree_node_t *)
           ((u_char *) rc_info_node - offsetof(ngx_rbtree_node_t, color));

    ngx_rbtree_delete(&ctx->sh->rbtree, node);

    ngx_http_tfs_rc_server_destroy_node(ctx, rc_info_node);
}
Example #23
0
void EIO_AfterWrite(uv_work_t* req) {
  QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
  WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);

  v8::Handle<v8::Value> argv[2];
  if(data->errorString[0]) {
    argv[0] = v8::Exception::Error(v8::String::New(data->errorString));
    argv[1] = v8::Undefined();
  } else {
    argv[0] = v8::Undefined();
    argv[1] = v8::Int32::New(data->result);
  }
  v8::Function::Cast(*data->callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);

  uv_mutex_lock(&write_queue_mutex);
  ngx_queue_remove(&queuedWrite->queue);

  if (!ngx_queue_empty(&write_queue)) {
    // Always pull the next work item from the head of the queue
    ngx_queue_t* head = ngx_queue_head(&write_queue);
    QueuedWrite* nextQueuedWrite = ngx_queue_data(head, QueuedWrite, queue);
    uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, EIO_AfterWrite);
  }
  uv_mutex_unlock(&write_queue_mutex);

  data->buffer.Dispose();
  data->callback.Dispose();
  delete data;
  delete queuedWrite;
}
Example #24
0
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
  assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
  assert(0 != events);

  if (w->fd == -1)
    return;

  assert(w->fd >= 0);

  /* Happens when uv__io_stop() is called on a handle that was never started. */
  if ((unsigned) w->fd >= loop->nwatchers)
    return;

  w->pevents &= ~events;

  if (w->pevents == 0) {
    ngx_queue_remove(&w->watcher_queue);
    ngx_queue_init(&w->watcher_queue);

    if (loop->watchers[w->fd] != NULL) {
      assert(loop->watchers[w->fd] == w);
      assert(loop->nfds > 0);
      loop->watchers[w->fd] = NULL;
      loop->nfds--;
      w->events = 0;
    }
  }
  else if (ngx_queue_empty(&w->watcher_queue))
    ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
}
Example #25
0
/* The buffers to be written must remain valid until the callback is called.
 * This is not required for the uv_buf_t array.
 */
int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) {
    uv_handle_t* handle = req->handle;
    assert(handle->fd >= 0);

    ngx_queue_init(&req->queue);
    req->type = UV_WRITE;

    /* TODO: Don't malloc for each write... */
    req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
    memcpy(req->bufs, bufs, bufcnt * sizeof(uv_buf_t));
    req->bufcnt = bufcnt;

    req->write_index = 0;
    handle->write_queue_size += uv__buf_count(bufs, bufcnt);

    /* Append the request to write_queue. */
    ngx_queue_insert_tail(&handle->write_queue, &req->queue);

    assert(!ngx_queue_empty(&handle->write_queue));
    assert(handle->write_watcher.cb == uv__tcp_io);
    assert(handle->write_watcher.data == handle);
    assert(handle->write_watcher.fd == handle->fd);

    ev_io_start(EV_DEFAULT_ &handle->write_watcher);

    return 0;
}
/* Note: must be called with the mutex locked */
static ngx_buffer_cache_entry_t*
ngx_buffer_cache_get_free_entry(ngx_buffer_cache_sh_t *cache)
{
	ngx_buffer_cache_entry_t* entry;

	if (!ngx_queue_empty(&cache->free_queue))
	{
		// return the free queue head
		return container_of(ngx_queue_head(&cache->free_queue), ngx_buffer_cache_entry_t, queue_node);
	}
	
	if ((u_char*)(cache->entries_end + 1) < cache->buffers_start)
	{
		// enlarge the entries buffer
		entry = cache->entries_end;
		cache->entries_end++;

		// initialize the state and add to free queue
		entry->state = CES_FREE;
		ngx_queue_insert_tail(&cache->free_queue, &entry->queue_node);
		return entry;
	}
	
	return ngx_buffer_cache_free_oldest_entry(cache, 0);
}
Example #27
0
static void uv__drain(uv_stream_t* stream) {
  uv_shutdown_t* req;

  assert(ngx_queue_empty(&stream->write_queue));
  assert(stream->write_queue_size == 0);

  uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);

  /* Shutdown? */
  if ((stream->flags & UV_STREAM_SHUTTING) &&
      !(stream->flags & UV_CLOSING) &&
      !(stream->flags & UV_STREAM_SHUT)) {
    assert(stream->shutdown_req);

    req = stream->shutdown_req;
    stream->shutdown_req = NULL;
    uv__req_unregister(stream->loop, req);

    if (shutdown(uv__stream_fd(stream), SHUT_WR)) {
      /* Error. Report it. User should call uv_close(). */
      uv__set_sys_error(stream->loop, errno);
      if (req->cb) {
        req->cb(req, -1);
      }
    } else {
      uv__set_sys_error(stream->loop, 0);
      ((uv_handle_t*) stream)->flags |= UV_STREAM_SHUT;
      if (req->cb) {
        req->cb(req, 0);
      }
    }
  }
}
static void
ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
{
    time_t                now;
    ngx_uint_t            i;
    ngx_queue_t          *q;
    ngx_resolver_node_t  *rn;

    ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver expire");

    now = ngx_time();

    for (i = 0; i < 2; i++) {
        if (ngx_queue_empty(queue)) {
            return;
        }

        q = ngx_queue_last(queue);

        rn = ngx_queue_data(q, ngx_resolver_node_t, queue);

        if (now <= rn->expire) {
            return;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
                       "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name);

        ngx_queue_remove(q);

        ngx_rbtree_delete(tree, &rn->node);

        ngx_resolver_free_node(r, rn);
    }
}
Example #29
0
// free_connections 中没有可用的连接, 从reusable_connections_queue获取
static void
ngx_drain_connections(void)
{
    ngx_int_t          i;
    ngx_queue_t       *q;
    ngx_connection_t  *c;

    // 清理32个keepalive连接,以回收一些连接池供新连接使用
    for (i = 0; i < 32; i++) {
        if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
            break;
        }
        // reusable连接队列是从头插入的,意味着越靠近队列尾部的连接,空闲未被  
        // 使用的时间就越长,这种情况下,优先回收它,类似LRU
        q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
        c = ngx_queue_data(q, ngx_connection_t, queue);

        ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
                       "reusing connection");

        // 这里的handler是ngx_http_keepalive_handler,这函数里,由于close被置1,  
        // 所以会执行ngx_http_close_connection来释放连接,这样也就发生了keepalive  
        // 连接被强制断掉的现象了。
        c->close = 1;
        c->read->handler(c->read);
    }
}
Example #30
0
static void
ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
     ngx_slab_pool_t *shpool, ngx_uint_t n)
{
    time_t              now, then;
    ngx_queue_t        *q;
    ngx_ssl_sess_id_t  *sess_id;

    now = ngx_time();

    while (n < 3) {
        
        if (ngx_queue_empty(&cache->expire_queue)) {
            return;
        }

        q = ngx_queue_last(&cache->expire_queue);

        sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);

        then = (time_t) sess_id->session->peer_cert;
        if (n++ != 0 && then > now) {
            return;
        }

        ngx_queue_remove(q);

        ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);

        ngx_slab_free_locked(shpool, sess_id->session);

        ngx_slab_free_locked(shpool, sess_id);
    }
}