FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

process: add _getActiveHandles(), _getActiveRequests() · johnson99/node@5f04065 · GitHub

Repository navigation

Commit 5f04065

Browse files
committed
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.).
1 parent 636add2 commit 5f04065

8 files changed

Lines changed: 252 additions & 2 deletions

File tree

‎LICENSE‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,31 @@ maintained libraries. The externally maintained libraries used by Node are:
550550
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
551551
THE SOFTWARE.
552552
"""
553+
554+
- src/ngx-queue.h ngx-queue.h is taken from the nginx source tree. nginx's
555+
license follows
556+
"""
557+
Copyright (C) 2002-2012 Igor Sysoev
558+
Copyright (C) 2011,2012 Nginx, Inc.
559+
560+
Redistribution and use in source and binary forms, with or without
561+
modification, are permitted provided that the following conditions
562+
are met:
563+
1. Redistributions of source code must retain the above copyright
564+
notice, this list of conditions and the following disclaimer.
565+
2. Redistributions in binary form must reproduce the above copyright
566+
notice, this list of conditions and the following disclaimer in the
567+
documentation and/or other materials provided with the distribution.
568+
569+
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
570+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
571+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
572+
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
573+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
574+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
575+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
576+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
577+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
578+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
579+
SUCH DAMAGE.
580+
"""

‎node.gyp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
'src/node_script.h',
108108
'src/node_string.h',
109109
'src/node_version.h',
110+
'src/ngx-queue.h',
110111
'src/pipe_wrap.h',
111112
'src/req_wrap.h',
112113
'src/slab_allocator.h',

‎src/handle_wrap.cc‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
#include "node.h"
23+
#include "ngx-queue.h"
2324
#include "handle_wrap.h"
2425

2526
namespace node {
2627

28+
using v8::Array;
2729
using v8::Object;
2830
using v8::Handle;
2931
using v8::Local;
@@ -52,6 +54,10 @@ using v8::Integer;
5254
}
5355

5456

57+
// defined in node.cc
58+
extern ngx_queue_t handle_wrap_queue;
59+
60+
5561
void HandleWrap::Initialize(Handle<Object> target) {
5662
/* Doesn't do anything at the moment. */
5763
}
@@ -125,6 +131,7 @@ HandleWrap::HandleWrap(Handle<Object> object, uv_handle_t* h) {
125131
assert(object->InternalFieldCount() > 0);
126132
object_ = v8::Persistent<v8::Object>::New(object);
127133
object_->SetPointerInInternalField(0, this);
134+
ngx_queue_insert_tail(&handle_wrap_queue, &handle_wrap_queue_);
128135
}
129136

130137

@@ -136,6 +143,7 @@ void HandleWrap::SetHandle(uv_handle_t* h) {
136143

137144
HandleWrap::~HandleWrap() {
138145
assert(object_.IsEmpty());
146+
ngx_queue_remove(&handle_wrap_queue_);
139147
}
140148

141149

‎src/handle_wrap.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#ifndef HANDLE_WRAP_H_
2323
#define HANDLE_WRAP_H_
2424

25+
#include "ngx-queue.h"
26+
2527
namespace node {
2628

2729
// Rules:
@@ -61,7 +63,9 @@ class HandleWrap {
6163
v8::Persistent<v8::Object> object_;
6264

6365
private:
66+
friend v8::Handle<v8::Value> GetActiveHandles(const v8::Arguments&);
6467
static void OnClose(uv_handle_t* handle);
68+
ngx_queue_t handle_wrap_queue_;
6569
// Using double underscore due to handle_ member in tcp_wrap. Probably
6670
// tcp_wrap should rename it's member to 'handle'.
6771
uv_handle_t* handle__;

‎src/ngx-queue.h‎

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
/*
3+
* Copyright (C) Igor Sysoev
4+
*/
5+
6+
7+
#ifndef NGX_QUEUE_H_INCLUDED_
8+
#define NGX_QUEUE_H_INCLUDED_
9+
10+
11+
typedef struct ngx_queue_s ngx_queue_t;
12+
13+
struct ngx_queue_s {
14+
ngx_queue_t *prev;
15+
ngx_queue_t *next;
16+
};
17+
18+
19+
#define ngx_queue_init(q) \
20+
(q)->prev = q; \
21+
(q)->next = q
22+
23+
24+
#define ngx_queue_empty(h) \
25+
(h == (h)->prev)
26+
27+
28+
#define ngx_queue_insert_head(h, x) \
29+
(x)->next = (h)->next; \
30+
(x)->next->prev = x; \
31+
(x)->prev = h; \
32+
(h)->next = x
33+
34+
35+
#define ngx_queue_insert_after ngx_queue_insert_head
36+
37+
38+
#define ngx_queue_insert_tail(h, x) \
39+
(x)->prev = (h)->prev; \
40+
(x)->prev->next = x; \
41+
(x)->next = h; \
42+
(h)->prev = x
43+
44+
45+
#define ngx_queue_head(h) \
46+
(h)->next
47+
48+
49+
#define ngx_queue_last(h) \
50+
(h)->prev
51+
52+
53+
#define ngx_queue_sentinel(h) \
54+
(h)
55+
56+
57+
#define ngx_queue_next(q) \
58+
(q)->next
59+
60+
61+
#define ngx_queue_prev(q) \
62+
(q)->prev
63+
64+
65+
#if (NGX_DEBUG)
66+
67+
#define ngx_queue_remove(x) \
68+
(x)->next->prev = (x)->prev; \
69+
(x)->prev->next = (x)->next; \
70+
(x)->prev = NULL; \
71+
(x)->next = NULL
72+
73+
#else
74+
75+
#define ngx_queue_remove(x) \
76+
(x)->next->prev = (x)->prev; \
77+
(x)->prev->next = (x)->next
78+
79+
#endif
80+
81+
82+
#define ngx_queue_split(h, q, n) \
83+
(n)->prev = (h)->prev; \
84+
(n)->prev->next = n; \
85+
(n)->next = q; \
86+
(h)->prev = (q)->prev; \
87+
(h)->prev->next = h; \
88+
(q)->prev = n;
89+
90+
91+
#define ngx_queue_add(h, n) \
92+
(h)->prev->next = (n)->next; \
93+
(n)->next->prev = (h)->prev; \
94+
(h)->prev = (n)->prev; \
95+
(h)->prev->next = h;
96+
97+
98+
#define ngx_queue_data(q, type, link) \
99+
(type *) ((unsigned char *) q - offsetof(type, link))
100+
101+
102+
#define ngx_queue_foreach(q, h) \
103+
for ((q) = ngx_queue_head(h); (q) != (h); (q) = ngx_queue_next(q))
104+
105+
106+
#endif /* NGX_QUEUE_H_INCLUDED_ */

‎src/node.cc‎

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
#include "node.h"
23-
#include "handle_wrap.h" // HandleWrap::GetActiveHandles()
23+
#include "req_wrap.h"
24+
#include "handle_wrap.h"
2425

2526
#include "uv.h"
2627

@@ -91,6 +92,9 @@ extern char **environ;
9192

9293
namespace node {
9394

95+
ngx_queue_t handle_wrap_queue = { &handle_wrap_queue, &handle_wrap_queue };
96+
ngx_queue_t req_wrap_queue = { &req_wrap_queue, &req_wrap_queue };
97+
9498
// declared in req_wrap.h
9599
Persistent<String> process_symbol;
96100
Persistent<String> domain_symbol;
@@ -1332,6 +1336,42 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
13321336
}
13331337

13341338

1339+
static Handle<Value> GetActiveRequests(const Arguments& args) {
1340+
HandleScope scope;
1341+
1342+
Local<Array> ary = Array::New();
1343+
ngx_queue_t* q = NULL;
1344+
int i = 0;
1345+
1346+
ngx_queue_foreach(q, &req_wrap_queue) {
1347+
ReqWrap<uv_req_t>* w = container_of(q, ReqWrap<uv_req_t>, req_wrap_queue_);
1348+
if (w->object_.IsEmpty()) continue;
1349+
ary->Set(i++, w->object_);
1350+
}
1351+
1352+
return scope.Close(ary);
1353+
}
1354+
1355+
1356+
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1357+
// implemented here for consistency with GetActiveRequests().
1358+
Handle<Value> GetActiveHandles(const Arguments& args) {
1359+
HandleScope scope;
1360+
1361+
Local<Array> ary = Array::New();
1362+
ngx_queue_t* q = NULL;
1363+
int i = 0;
1364+
1365+
ngx_queue_foreach(q, &handle_wrap_queue) {
1366+
HandleWrap* w = container_of(q, HandleWrap, handle_wrap_queue_);
1367+
if (w->object_.IsEmpty() || w->unref) continue;
1368+
ary->Set(i++, w->object_);
1369+
}
1370+
1371+
return scope.Close(ary);
1372+
}
1373+
1374+
13351375
static Handle<Value> Abort(const Arguments& args) {
13361376
abort();
13371377
return Undefined();
@@ -2237,6 +2277,8 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
22372277

22382278

22392279
// define various internal methods
2280+
NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests);
2281+
NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles);
22402282
NODE_SET_METHOD(process, "_needTickCallback", NeedTickCallback);
22412283
NODE_SET_METHOD(process, "reallyExit", Exit);
22422284
NODE_SET_METHOD(process, "abort", Abort);

‎src/req_wrap.h‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
#ifndef REQ_WRAP_H_
2323
#define REQ_WRAP_H_
2424

25+
#include "ngx-queue.h"
26+
2527
namespace node {
2628

2729
// defined in node.cc
2830
extern v8::Persistent<v8::String> process_symbol;
2931
extern v8::Persistent<v8::String> domain_symbol;
32+
extern ngx_queue_t req_wrap_queue;
3033

3134
template <typename T>
3235
class ReqWrap {
@@ -45,10 +48,13 @@ class ReqWrap {
4548
// fprintf(stderr, "setting domain on ReqWrap\n");
4649
object_->Set(domain_symbol, domain);
4750
}
51+
52+
ngx_queue_insert_tail(&req_wrap_queue, &req_wrap_queue_);
4853
}
4954

5055

5156
~ReqWrap() {
57+
ngx_queue_remove(&req_wrap_queue_);
5258
// Assert that someone has called Dispatched()
5359
assert(req_.data == this);
5460
assert(!object_.IsEmpty());
@@ -62,8 +68,9 @@ class ReqWrap {
6268
}
6369

6470
v8::Persistent<v8::Object> object_;
65-
T req_;
71+
ngx_queue_t req_wrap_queue_;
6672
void* data_;
73+
T req_; // *must* be last, GetActiveRequests() in node.cc depends on it
6774
};
6875

6976

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
var spawn = require('child_process').spawn;
25+
var net = require('net');
26+
27+
function expect(activeHandles, activeRequests) {
28+
assert.equal(process._getActiveHandles().length, activeHandles);
29+
assert.equal(process._getActiveRequests().length, activeRequests);
30+
}
31+
32+
(function() {
33+
expect(0, 0);
34+
var server = net.createServer().listen(common.PORT);
35+
expect(1, 0);
36+
server.close();
37+
expect(1, 0); // server handle doesn't shut down until next tick
38+
})();
39+
40+
(function() {
41+
expect(1, 0);
42+
var conn = net.createConnection(common.PORT);
43+
conn.on('error', function() { /* ignore */ });
44+
expect(2, 1);
45+
conn.destroy();
46+
expect(2, 1); // client handle doesn't shut down until next tick
47+
})();
48+
49+
process.nextTick(function() {
50+
process.nextTick(function() {
51+
// the handles should be gone but the connect req could still be alive
52+
assert.equal(process._getActiveHandles().length, 0);
53+
});
54+
});

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL