summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2012-04-28 18:45:10 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2012-05-15 21:00:27 +0200
commit5f0406534ca4a465d11892a747a38c0e5c884cf2 (patch)
treed77de6abca80b95d2729ecdb9d72e0f5b5370780 /src
parent636add246ca78be5c374cfd951c76de7f1010fb9 (diff)
downloadandroid-node-v8-5f0406534ca4a465d11892a747a38c0e5c884cf2.tar.gz
android-node-v8-5f0406534ca4a465d11892a747a38c0e5c884cf2.tar.bz2
android-node-v8-5f0406534ca4a465d11892a747a38c0e5c884cf2.zip
process: add _getActiveHandles(), _getActiveRequests()
* process._getActiveHandles() returns a list containing all active handles (timers, sockets, etc.) that have not been unref'd. * process._getActiveRequests() returns a list of active requests (in-flight actions like connecting to a remote host, writing data to a socket, etc.).
Diffstat (limited to 'src')
-rw-r--r--src/handle_wrap.cc8
-rw-r--r--src/handle_wrap.h4
-rw-r--r--src/ngx-queue.h106
-rw-r--r--src/node.cc44
-rw-r--r--src/req_wrap.h9
5 files changed, 169 insertions, 2 deletions
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index d9621b4c4b..11777a88c3 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -20,10 +20,12 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "node.h"
+#include "ngx-queue.h"
#include "handle_wrap.h"
namespace node {
+using v8::Array;
using v8::Object;
using v8::Handle;
using v8::Local;
@@ -52,6 +54,10 @@ using v8::Integer;
}
+// defined in node.cc
+extern ngx_queue_t handle_wrap_queue;
+
+
void HandleWrap::Initialize(Handle<Object> target) {
/* Doesn't do anything at the moment. */
}
@@ -125,6 +131,7 @@ HandleWrap::HandleWrap(Handle<Object> object, uv_handle_t* h) {
assert(object->InternalFieldCount() > 0);
object_ = v8::Persistent<v8::Object>::New(object);
object_->SetPointerInInternalField(0, this);
+ ngx_queue_insert_tail(&handle_wrap_queue, &handle_wrap_queue_);
}
@@ -136,6 +143,7 @@ void HandleWrap::SetHandle(uv_handle_t* h) {
HandleWrap::~HandleWrap() {
assert(object_.IsEmpty());
+ ngx_queue_remove(&handle_wrap_queue_);
}
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
index b9cf31e8eb..c6dd4c9d6a 100644
--- a/src/handle_wrap.h
+++ b/src/handle_wrap.h
@@ -22,6 +22,8 @@
#ifndef HANDLE_WRAP_H_
#define HANDLE_WRAP_H_
+#include "ngx-queue.h"
+
namespace node {
// Rules:
@@ -61,7 +63,9 @@ class HandleWrap {
v8::Persistent<v8::Object> object_;
private:
+ friend v8::Handle<v8::Value> GetActiveHandles(const v8::Arguments&);
static void OnClose(uv_handle_t* handle);
+ ngx_queue_t handle_wrap_queue_;
// Using double underscore due to handle_ member in tcp_wrap. Probably
// tcp_wrap should rename it's member to 'handle'.
uv_handle_t* handle__;
diff --git a/src/ngx-queue.h b/src/ngx-queue.h
new file mode 100644
index 0000000000..7058ce408d
--- /dev/null
+++ b/src/ngx-queue.h
@@ -0,0 +1,106 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef NGX_QUEUE_H_INCLUDED_
+#define NGX_QUEUE_H_INCLUDED_
+
+
+typedef struct ngx_queue_s ngx_queue_t;
+
+struct ngx_queue_s {
+ ngx_queue_t *prev;
+ ngx_queue_t *next;
+};
+
+
+#define ngx_queue_init(q) \
+ (q)->prev = q; \
+ (q)->next = q
+
+
+#define ngx_queue_empty(h) \
+ (h == (h)->prev)
+
+
+#define ngx_queue_insert_head(h, x) \
+ (x)->next = (h)->next; \
+ (x)->next->prev = x; \
+ (x)->prev = h; \
+ (h)->next = x
+
+
+#define ngx_queue_insert_after ngx_queue_insert_head
+
+
+#define ngx_queue_insert_tail(h, x) \
+ (x)->prev = (h)->prev; \
+ (x)->prev->next = x; \
+ (x)->next = h; \
+ (h)->prev = x
+
+
+#define ngx_queue_head(h) \
+ (h)->next
+
+
+#define ngx_queue_last(h) \
+ (h)->prev
+
+
+#define ngx_queue_sentinel(h) \
+ (h)
+
+
+#define ngx_queue_next(q) \
+ (q)->next
+
+
+#define ngx_queue_prev(q) \
+ (q)->prev
+
+
+#if (NGX_DEBUG)
+
+#define ngx_queue_remove(x) \
+ (x)->next->prev = (x)->prev; \
+ (x)->prev->next = (x)->next; \
+ (x)->prev = NULL; \
+ (x)->next = NULL
+
+#else
+
+#define ngx_queue_remove(x) \
+ (x)->next->prev = (x)->prev; \
+ (x)->prev->next = (x)->next
+
+#endif
+
+
+#define ngx_queue_split(h, q, n) \
+ (n)->prev = (h)->prev; \
+ (n)->prev->next = n; \
+ (n)->next = q; \
+ (h)->prev = (q)->prev; \
+ (h)->prev->next = h; \
+ (q)->prev = n;
+
+
+#define ngx_queue_add(h, n) \
+ (h)->prev->next = (n)->next; \
+ (n)->next->prev = (h)->prev; \
+ (h)->prev = (n)->prev; \
+ (h)->prev->next = h;
+
+
+#define ngx_queue_data(q, type, link) \
+ (type *) ((unsigned char *) q - offsetof(type, link))
+
+
+#define ngx_queue_foreach(q, h) \
+ for ((q) = ngx_queue_head(h); (q) != (h); (q) = ngx_queue_next(q))
+
+
+#endif /* NGX_QUEUE_H_INCLUDED_ */
diff --git a/src/node.cc b/src/node.cc
index bca0ea28eb..41dab06e52 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -20,7 +20,8 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "node.h"
-#include "handle_wrap.h" // HandleWrap::GetActiveHandles()
+#include "req_wrap.h"
+#include "handle_wrap.h"
#include "uv.h"
@@ -91,6 +92,9 @@ extern char **environ;
namespace node {
+ngx_queue_t handle_wrap_queue = { &handle_wrap_queue, &handle_wrap_queue };
+ngx_queue_t req_wrap_queue = { &req_wrap_queue, &req_wrap_queue };
+
// declared in req_wrap.h
Persistent<String> process_symbol;
Persistent<String> domain_symbol;
@@ -1332,6 +1336,42 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
}
+static Handle<Value> GetActiveRequests(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Array> ary = Array::New();
+ ngx_queue_t* q = NULL;
+ int i = 0;
+
+ ngx_queue_foreach(q, &req_wrap_queue) {
+ ReqWrap<uv_req_t>* w = container_of(q, ReqWrap<uv_req_t>, req_wrap_queue_);
+ if (w->object_.IsEmpty()) continue;
+ ary->Set(i++, w->object_);
+ }
+
+ return scope.Close(ary);
+}
+
+
+// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
+// implemented here for consistency with GetActiveRequests().
+Handle<Value> GetActiveHandles(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Array> ary = Array::New();
+ ngx_queue_t* q = NULL;
+ int i = 0;
+
+ ngx_queue_foreach(q, &handle_wrap_queue) {
+ HandleWrap* w = container_of(q, HandleWrap, handle_wrap_queue_);
+ if (w->object_.IsEmpty() || w->unref) continue;
+ ary->Set(i++, w->object_);
+ }
+
+ return scope.Close(ary);
+}
+
+
static Handle<Value> Abort(const Arguments& args) {
abort();
return Undefined();
@@ -2237,6 +2277,8 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
// define various internal methods
+ NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests);
+ NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles);
NODE_SET_METHOD(process, "_needTickCallback", NeedTickCallback);
NODE_SET_METHOD(process, "reallyExit", Exit);
NODE_SET_METHOD(process, "abort", Abort);
diff --git a/src/req_wrap.h b/src/req_wrap.h
index 11c7d12044..ba56821bbe 100644
--- a/src/req_wrap.h
+++ b/src/req_wrap.h
@@ -22,11 +22,14 @@
#ifndef REQ_WRAP_H_
#define REQ_WRAP_H_
+#include "ngx-queue.h"
+
namespace node {
// defined in node.cc
extern v8::Persistent<v8::String> process_symbol;
extern v8::Persistent<v8::String> domain_symbol;
+extern ngx_queue_t req_wrap_queue;
template <typename T>
class ReqWrap {
@@ -45,10 +48,13 @@ class ReqWrap {
// fprintf(stderr, "setting domain on ReqWrap\n");
object_->Set(domain_symbol, domain);
}
+
+ ngx_queue_insert_tail(&req_wrap_queue, &req_wrap_queue_);
}
~ReqWrap() {
+ ngx_queue_remove(&req_wrap_queue_);
// Assert that someone has called Dispatched()
assert(req_.data == this);
assert(!object_.IsEmpty());
@@ -62,8 +68,9 @@ class ReqWrap {
}
v8::Persistent<v8::Object> object_;
- T req_;
+ ngx_queue_t req_wrap_queue_;
void* data_;
+ T req_; // *must* be last, GetActiveRequests() in node.cc depends on it
};