@@ -28,6 +28,26 @@ var inherits = util.inherits;
2828// a few side effects.
2929EventEmitter . usingDomains = true ;
3030
31+ // overwrite process.domain with a getter/setter that will allow for more
32+ // effective optimizations
33+ var _domain = [ null ] ;
34+ Object . defineProperty ( process , 'domain' , {
35+ enumerable : true ,
36+ get : function ( ) {
37+ return _domain [ 0 ] ;
38+ } ,
39+ set : function ( arg ) {
40+ return _domain [ 0 ] = arg ;
41+ }
42+ } ) ;
43+
44+ // objects with external array data are excellent ways to communicate state
45+ // between js and c++ w/o much overhead
46+ var _domain_flag = { } ;
47+
48+ // let the process know we're using domains
49+ process . _setupDomainUse ( _domain , _domain_flag ) ;
50+
3151exports . Domain = Domain ;
3252
3353exports . create = exports . createDomain = function ( ) {
@@ -42,71 +62,66 @@ exports._stack = stack;
4262exports . active = null ;
4363
4464
45- var listenerObj = {
46- error : function errorHandler ( domain , er ) {
47- var caught = false ;
48- // ignore errors on disposed domains.
49- //
50- // XXX This is a bit stupid. We should probably get rid of
51- // domain.dispose() altogether. It's almost always a terrible
52- // idea. --isaacs
53- if ( domain . _disposed )
54- return true ;
55-
56- er . domain = domain ;
57- er . domainThrown = true ;
58- // wrap this in a try/catch so we don't get infinite throwing
59- try {
60- // One of three things will happen here.
61- //
62- // 1. There is a handler, caught = true
63- // 2. There is no handler, caught = false
64- // 3. It throws, caught = false
65- //
66- // If caught is false after this, then there's no need to exit()
67- // the domain, because we're going to crash the process anyway.
68- caught = domain . emit ( 'error' , er ) ;
69-
70- if ( stack . length === 0 )
71- process . removeAsyncListener ( domain . _listener ) ;
72-
73- // Exit all domains on the stack. Uncaught exceptions end the
74- // current tick and no domains should be left on the stack
75- // between ticks.
76- stack . length = 0 ;
77- exports . active = process . domain = null ;
78- } catch ( er2 ) {
79- // The domain error handler threw! oh no!
80- // See if another domain can catch THIS error,
81- // or else crash on the original one.
82- // If the user already exited it, then don't double-exit.
83- if ( domain === exports . active ) {
84- stack . pop ( ) ;
85- }
86- if ( stack . length ) {
87- exports . active = process . domain = stack [ stack . length - 1 ] ;
88- caught = process . _fatalException ( er2 ) ;
89- } else {
90- caught = false ;
91- }
92- return caught ;
93- }
94- return caught ;
95- }
96- } ;
97-
98-
9965inherits ( Domain , EventEmitter ) ;
10066
10167function Domain ( ) {
10268 EventEmitter . call ( this ) ;
69+
10370 this . members = [ ] ;
104- this . _listener = process . createAsyncListener ( listenerObj , this ) ;
10571}
10672
10773Domain . prototype . members = undefined ;
10874Domain . prototype . _disposed = undefined ;
109- Domain . prototype . _listener = undefined ;
75+
76+
77+ // Called by process._fatalException in case an error was thrown.
78+ Domain . prototype . _errorHandler = function errorHandler ( er ) {
79+ var caught = false ;
80+ // ignore errors on disposed domains.
81+ //
82+ // XXX This is a bit stupid. We should probably get rid of
83+ // domain.dispose() altogether. It's almost always a terrible
84+ // idea. --isaacs
85+ if ( this . _disposed )
86+ return true ;
87+
88+ er . domain = this ;
89+ er . domainThrown = true ;
90+ // wrap this in a try/catch so we don't get infinite throwing
91+ try {
92+ // One of three things will happen here.
93+ //
94+ // 1. There is a handler, caught = true
95+ // 2. There is no handler, caught = false
96+ // 3. It throws, caught = false
97+ //
98+ // If caught is false after this, then there's no need to exit()
99+ // the domain, because we're going to crash the process anyway.
100+ caught = this . emit ( 'error' , er ) ;
101+
102+ // Exit all domains on the stack. Uncaught exceptions end the
103+ // current tick and no domains should be left on the stack
104+ // between ticks.
105+ stack . length = 0 ;
106+ exports . active = process . domain = null ;
107+ } catch ( er2 ) {
108+ // The domain error handler threw! oh no!
109+ // See if another domain can catch THIS error,
110+ // or else crash on the original one.
111+ // If the user already exited it, then don't double-exit.
112+ if ( this === exports . active ) {
113+ stack . pop ( ) ;
114+ }
115+ if ( stack . length ) {
116+ exports . active = process . domain = stack [ stack . length - 1 ] ;
117+ caught = process . _fatalException ( er2 ) ;
118+ } else {
119+ caught = false ;
120+ }
121+ return caught ;
122+ }
123+ return caught ;
124+ } ;
110125
111126
112127Domain . prototype . enter = function ( ) {
@@ -116,22 +131,20 @@ Domain.prototype.enter = function() {
116131 // to push it onto the stack so that we can pop it later.
117132 exports . active = process . domain = this ;
118133 stack . push ( this ) ;
119-
120- process . addAsyncListener ( this . _listener ) ;
134+ _domain_flag [ 0 ] = stack . length ;
121135} ;
122136
123137
124138Domain . prototype . exit = function ( ) {
125139 if ( this . _disposed ) return ;
126140
127- process . removeAsyncListener ( this . _listener ) ;
128-
129141 // exit all domains until this one.
130142 var index = stack . lastIndexOf ( this ) ;
131143 if ( index !== - 1 )
132144 stack . splice ( index + 1 ) ;
133145 else
134146 stack . length = 0 ;
147+ _domain_flag [ 0 ] = stack . length ;
135148
136149 exports . active = stack [ stack . length - 1 ] ;
137150 process . domain = exports . active ;
@@ -165,13 +178,6 @@ Domain.prototype.add = function(ee) {
165178
166179 ee . domain = this ;
167180 this . members . push ( ee ) ;
168-
169- // Adding the domain._listener to the Wrap associated with the event
170- // emitter instance will be done automatically either on class
171- // instantiation or manually, like in cases of net listen().
172- // The reason it cannot be done here is because in specific cases the
173- // _handle is not created on EE instantiation, so there's no place to
174- // add the listener.
175181} ;
176182
177183
@@ -180,24 +186,6 @@ Domain.prototype.remove = function(ee) {
180186 var index = this . members . indexOf ( ee ) ;
181187 if ( index !== - 1 )
182188 this . members . splice ( index , 1 ) ;
183-
184- // First check if the ee is a handle itself.
185- if ( ee . removeAsyncListener )
186- ee . removeAsyncListener ( this . _listener ) ;
187-
188- // Manually remove the asyncListener from the handle, if possible.
189- if ( ee . _handle && ee . _handle . removeAsyncListener )
190- ee . _handle . removeAsyncListener ( this . _listener ) ;
191-
192- // TODO(trevnorris): Are there cases where the handle doesn't live on
193- // the ee or the _handle.
194-
195- // TODO(trevnorris): For debugging that we've missed adding AsyncWrap's
196- // methods to a handle somewhere on the native side.
197- if ( ee . _handle && ! ee . _handle . removeAsyncListener ) {
198- process . _rawDebug ( 'Wrap handle is missing AsyncWrap methods' ) ;
199- process . abort ( ) ;
200- }
201189} ;
202190
203191
0 commit comments