| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 636add2 commit 5f04065
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -550,3 +550,31 @@ maintained libraries. The externally maintained libraries used by Node are: | |||
| 550 | 550 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 551 | 551 | THE SOFTWARE. | |
| 552 | 552 | """ | |
| 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 | + """ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -107,6 +107,7 @@ | |||
| 107 | 107 | 'src/node_script.h', | |
| 108 | 108 | 'src/node_string.h', | |
| 109 | 109 | 'src/node_version.h', | |
| 110 | + 'src/ngx-queue.h', | ||
| 110 | 111 | 'src/pipe_wrap.h', | |
| 111 | 112 | 'src/req_wrap.h', | |
| 112 | 113 | 'src/slab_allocator.h', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,10 +20,12 @@ | |||
| 20 | 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | 21 | ||
| 22 | 22 | #include "node.h" | |
| 23 | + #include "ngx-queue.h" | ||
| 23 | 24 | #include "handle_wrap.h" | |
| 24 | 25 | ||
| 25 | 26 | namespace node { | |
| 26 | 27 | ||
| 28 | + using v8::Array; | ||
| 27 | 29 | using v8::Object; | |
| 28 | 30 | using v8::Handle; | |
| 29 | 31 | using v8::Local; | |
@@ -52,6 +54,10 @@ using v8::Integer; | |||
| 52 | 54 | } | |
| 53 | 55 | ||
| 54 | 56 | ||
| 57 | + // defined in node.cc | ||
| 58 | + extern ngx_queue_t handle_wrap_queue; | ||
| 59 | + | ||
| 60 | + | ||
| 55 | 61 | void HandleWrap::Initialize(Handle<Object> target) { | |
| 56 | 62 | /* Doesn't do anything at the moment. */ | |
| 57 | 63 | } | |
@@ -125,6 +131,7 @@ HandleWrap::HandleWrap(Handle<Object> object, uv_handle_t* h) { | |||
| 125 | 131 | assert(object->InternalFieldCount() > 0); | |
| 126 | 132 | object_ = v8::Persistent<v8::Object>::New(object); | |
| 127 | 133 | object_->SetPointerInInternalField(0, this); | |
| 134 | + ngx_queue_insert_tail(&handle_wrap_queue, &handle_wrap_queue_); | ||
| 128 | 135 | } | |
| 129 | 136 | ||
| 130 | 137 | ||
@@ -136,6 +143,7 @@ void HandleWrap::SetHandle(uv_handle_t* h) { | |||
| 136 | 143 | ||
| 137 | 144 | HandleWrap::~HandleWrap() { | |
| 138 | 145 | assert(object_.IsEmpty()); | |
| 146 | + ngx_queue_remove(&handle_wrap_queue_); | ||
| 139 | 147 | } | |
| 140 | 148 | ||
| 141 | 149 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,8 @@ | |||
| 22 | 22 | #ifndef HANDLE_WRAP_H_ | |
| 23 | 23 | #define HANDLE_WRAP_H_ | |
| 24 | 24 | ||
| 25 | + #include "ngx-queue.h" | ||
| 26 | + | ||
| 25 | 27 | namespace node { | |
| 26 | 28 | ||
| 27 | 29 | // Rules: | |
@@ -61,7 +63,9 @@ class HandleWrap { | |||
| 61 | 63 | v8::Persistent<v8::Object> object_; | |
| 62 | 64 | ||
| 63 | 65 | private: | |
| 66 | + friend v8::Handle<v8::Value> GetActiveHandles(const v8::Arguments&); | ||
| 64 | 67 | static void OnClose(uv_handle_t* handle); | |
| 68 | + ngx_queue_t handle_wrap_queue_; | ||
| 65 | 69 | // Using double underscore due to handle_ member in tcp_wrap. Probably | |
| 66 | 70 | // tcp_wrap should rename it's member to 'handle'. | |
| 67 | 71 | uv_handle_t* handle__; | |
| Original file line number | Diff line number | Diff 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_ */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,7 +20,8 @@ | |||
| 20 | 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | 21 | ||
| 22 | 22 | #include "node.h" | |
| 23 | - #include "handle_wrap.h" // HandleWrap::GetActiveHandles() | ||
| 23 | + #include "req_wrap.h" | ||
| 24 | + #include "handle_wrap.h" | ||
| 24 | 25 | ||
| 25 | 26 | #include "uv.h" | |
| 26 | 27 | ||
@@ -91,6 +92,9 @@ extern char **environ; | |||
| 91 | 92 | ||
| 92 | 93 | namespace node { | |
| 93 | 94 | ||
| 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 | + | ||
| 94 | 98 | // declared in req_wrap.h | |
| 95 | 99 | Persistent<String> process_symbol; | |
| 96 | 100 | Persistent<String> domain_symbol; | |
@@ -1332,6 +1336,42 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) { | |||
| 1332 | 1336 | } | |
| 1333 | 1337 | ||
| 1334 | 1338 | ||
| 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 | + | ||
| 1335 | 1375 | static Handle<Value> Abort(const Arguments& args) { | |
| 1336 | 1376 | abort(); | |
| 1337 | 1377 | return Undefined(); | |
@@ -2237,6 +2277,8 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) { | |||
| 2237 | 2277 | ||
| 2238 | 2278 | ||
| 2239 | 2279 | // define various internal methods | |
| 2280 | + NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests); | ||
| 2281 | + NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles); | ||
| 2240 | 2282 | NODE_SET_METHOD(process, "_needTickCallback", NeedTickCallback); | |
| 2241 | 2283 | NODE_SET_METHOD(process, "reallyExit", Exit); | |
| 2242 | 2284 | NODE_SET_METHOD(process, "abort", Abort); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,11 +22,14 @@ | |||
| 22 | 22 | #ifndef REQ_WRAP_H_ | |
| 23 | 23 | #define REQ_WRAP_H_ | |
| 24 | 24 | ||
| 25 | + #include "ngx-queue.h" | ||
| 26 | + | ||
| 25 | 27 | namespace node { | |
| 26 | 28 | ||
| 27 | 29 | // defined in node.cc | |
| 28 | 30 | extern v8::Persistent<v8::String> process_symbol; | |
| 29 | 31 | extern v8::Persistent<v8::String> domain_symbol; | |
| 32 | + extern ngx_queue_t req_wrap_queue; | ||
| 30 | 33 | ||
| 31 | 34 | template <typename T> | |
| 32 | 35 | class ReqWrap { | |
@@ -45,10 +48,13 @@ class ReqWrap { | |||
| 45 | 48 | // fprintf(stderr, "setting domain on ReqWrap\n"); | |
| 46 | 49 | object_->Set(domain_symbol, domain); | |
| 47 | 50 | } | |
| 51 | + | ||
| 52 | + ngx_queue_insert_tail(&req_wrap_queue, &req_wrap_queue_); | ||
| 48 | 53 | } | |
| 49 | 54 | ||
| 50 | 55 | ||
| 51 | 56 | ~ReqWrap() { | |
| 57 | + ngx_queue_remove(&req_wrap_queue_); | ||
| 52 | 58 | // Assert that someone has called Dispatched() | |
| 53 | 59 | assert(req_.data == this); | |
| 54 | 60 | assert(!object_.IsEmpty()); | |
@@ -62,8 +68,9 @@ class ReqWrap { | |||
| 62 | 68 | } | |
| 63 | 69 | ||
| 64 | 70 | v8::Persistent<v8::Object> object_; | |
| 65 | - T req_; | ||
| 71 | + ngx_queue_t req_wrap_queue_; | ||
| 66 | 72 | void* data_; | |
| 73 | + T req_; // *must* be last, GetActiveRequests() in node.cc depends on it | ||
| 67 | 74 | }; | |
| 68 | 75 | ||
| 69 | 76 | ||
| Original file line number | Diff line number | Diff 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 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments