diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2012-04-28 18:45:10 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2012-05-15 21:00:27 +0200 |
commit | 5f0406534ca4a465d11892a747a38c0e5c884cf2 (patch) | |
tree | d77de6abca80b95d2729ecdb9d72e0f5b5370780 /src | |
parent | 636add246ca78be5c374cfd951c76de7f1010fb9 (diff) | |
download | android-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.cc | 8 | ||||
-rw-r--r-- | src/handle_wrap.h | 4 | ||||
-rw-r--r-- | src/ngx-queue.h | 106 | ||||
-rw-r--r-- | src/node.cc | 44 | ||||
-rw-r--r-- | src/req_wrap.h | 9 |
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 }; |