6db4a08c2a1e9413f6de9f4f412a5499eba1f68c
[platform/upstream/nodejs.git] / src / env.h
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 #ifndef SRC_ENV_H_
23 #define SRC_ENV_H_
24
25 #include "ares.h"
26 #include "tree.h"
27 #include "util.h"
28 #include "uv.h"
29 #include "v8.h"
30
31 #include <stdint.h>
32
33 // Caveat emptor: we're going slightly crazy with macros here but the end
34 // hopefully justifies the means. We have a lot of per-context properties
35 // and adding and maintaining their getters and setters by hand would be
36 // a nightmare so let's make the preprocessor generate them for us.
37 //
38 // Make sure that any macros defined here are undefined again at the bottom
39 // of context-inl.h. The sole exception is NODE_CONTEXT_EMBEDDER_DATA_INDEX,
40 // it may have been defined externally.
41 namespace node {
42
43 // Pick an index that's hopefully out of the way when we're embedded inside
44 // another application. Performance-wise or memory-wise it doesn't matter:
45 // Context::SetAlignedPointerInEmbedderData() is backed by a FixedArray,
46 // worst case we pay a one-time penalty for resizing the array.
47 #ifndef NODE_CONTEXT_EMBEDDER_DATA_INDEX
48 #define NODE_CONTEXT_EMBEDDER_DATA_INDEX 32
49 #endif
50
51 // Strings are per-isolate primitives but Environment proxies them
52 // for the sake of convenience.
53 #define PER_ISOLATE_STRING_PROPERTIES(V)                                      \
54   V(address_string, "address")                                                \
55   V(atime_string, "atime")                                                    \
56   V(async_queue_string, "_asyncQueue")                                        \
57   V(birthtime_string, "birthtime")                                            \
58   V(blksize_string, "blksize")                                                \
59   V(blocks_string, "blocks")                                                  \
60   V(buffer_string, "buffer")                                                  \
61   V(bytes_string, "bytes")                                                    \
62   V(callback_string, "callback")                                              \
63   V(change_string, "change")                                                  \
64   V(close_string, "close")                                                    \
65   V(code_string, "code")                                                      \
66   V(ctime_string, "ctime")                                                    \
67   V(dev_string, "dev")                                                        \
68   V(disposed_string, "_disposed")                                             \
69   V(enter_string, "enter")                                                    \
70   V(errno_string, "errno")                                                    \
71   V(exit_string, "exit")                                                      \
72   V(exponent_string, "exponent")                                              \
73   V(exports_string, "exports")                                                \
74   V(ext_key_usage_string, "ext_key_usage")                                    \
75   V(family_string, "family")                                                  \
76   V(fatal_exception_string, "_fatalException")                                \
77   V(fingerprint_string, "fingerprint")                                        \
78   V(gid_string, "gid")                                                        \
79   V(handle_string, "handle")                                                  \
80   V(headers_string, "headers")                                                \
81   V(heap_total_string, "heapTotal")                                           \
82   V(heap_used_string, "heapUsed")                                             \
83   V(immediate_callback_string, "_immediateCallback")                          \
84   V(ino_string, "ino")                                                        \
85   V(ipv4_string, "IPv4")                                                      \
86   V(ipv6_string, "IPv6")                                                      \
87   V(issuer_string, "issuer")                                                  \
88   V(method_string, "method")                                                  \
89   V(mode_string, "mode")                                                      \
90   V(modulus_string, "modulus")                                                \
91   V(mtime_string, "mtime")                                                    \
92   V(name_string, "name")                                                      \
93   V(nlink_string, "nlink")                                                    \
94   V(onchange_string, "onchange")                                              \
95   V(onclienthello_string, "onclienthello")                                    \
96   V(oncomplete_string, "oncomplete")                                          \
97   V(onconnection_string, "onconnection")                                      \
98   V(ondone_string, "ondone")                                                  \
99   V(onerror_string, "onerror")                                                \
100   V(onexit_string, "onexit")                                                  \
101   V(onhandshakedone_string, "onhandshakedone")                                \
102   V(onhandshakestart_string, "onhandshakestart")                              \
103   V(onmessage_string, "onmessage")                                            \
104   V(onnewsession_string, "onnewsession")                                      \
105   V(onread_string, "onread")                                                  \
106   V(onselect_string, "onselect")                                              \
107   V(onsignal_string, "onsignal")                                              \
108   V(onstop_string, "onstop")                                                  \
109   V(path_string, "path")                                                      \
110   V(port_string, "port")                                                      \
111   V(rdev_string, "rdev")                                                      \
112   V(rename_string, "rename")                                                  \
113   V(rss_string, "rss")                                                        \
114   V(serial_number_string, "serialNumber")                                     \
115   V(servername_string, "servername")                                          \
116   V(session_id_string, "sessionId")                                           \
117   V(should_keep_alive_string, "shouldKeepAlive")                              \
118   V(size_string, "size")                                                      \
119   V(smalloc_p_string, "_smalloc_p")                                           \
120   V(sni_context_string, "sni_context")                                        \
121   V(status_code_string, "statusCode")                                         \
122   V(status_message_string, "statusMessage")                                   \
123   V(subject_string, "subject")                                                \
124   V(subjectaltname_string, "subjectaltname")                                  \
125   V(syscall_string, "syscall")                                                \
126   V(tls_ticket_string, "tlsTicket")                                           \
127   V(uid_string, "uid")                                                        \
128   V(upgrade_string, "upgrade")                                                \
129   V(url_string, "url")                                                        \
130   V(valid_from_string, "valid_from")                                          \
131   V(valid_to_string, "valid_to")                                              \
132   V(version_major_string, "versionMajor")                                     \
133   V(version_minor_string, "versionMinor")                                     \
134   V(version_string, "version")                                                \
135   V(write_queue_size_string, "writeQueueSize")                                \
136
137 #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)                           \
138   V(async_listener_load_function, v8::Function)                               \
139   V(async_listener_push_function, v8::Function)                               \
140   V(async_listener_run_function, v8::Function)                                \
141   V(async_listener_strip_function, v8::Function)                              \
142   V(async_listener_unload_function, v8::Function)                             \
143   V(binding_cache_object, v8::Object)                                         \
144   V(buffer_constructor_function, v8::Function)                                \
145   V(context, v8::Context)                                                     \
146   V(module_load_list_array, v8::Array)                                        \
147   V(pipe_constructor_template, v8::FunctionTemplate)                          \
148   V(process_object, v8::Object)                                               \
149   V(script_context_constructor_template, v8::FunctionTemplate)                \
150   V(script_data_constructor_function, v8::Function)                           \
151   V(secure_context_constructor_template, v8::FunctionTemplate)                \
152   V(stats_constructor_function, v8::Function)                                 \
153   V(tcp_constructor_template, v8::FunctionTemplate)                           \
154   V(tick_callback_function, v8::Function)                                     \
155   V(tls_wrap_constructor_function, v8::Function)                              \
156   V(tty_constructor_template, v8::FunctionTemplate)                           \
157   V(udp_constructor_function, v8::Function)                                   \
158
159 class Environment;
160
161 // TODO(bnoordhuis) Rename struct, the ares_ prefix implies it's part
162 // of the c-ares API while the _t suffix implies it's a typedef.
163 struct ares_task_t {
164   Environment* env;
165   ares_socket_t sock;
166   uv_poll_t poll_watcher;
167   RB_ENTRY(ares_task_t) node;
168 };
169
170 RB_HEAD(ares_task_list, ares_task_t);
171
172 class Environment {
173  public:
174   class AsyncListener {
175    public:
176     inline uint32_t* fields();
177     inline int fields_count() const;
178     inline uint32_t count() const;
179
180    private:
181     friend class Environment;  // So we can call the constructor.
182     inline AsyncListener();
183
184     enum Fields {
185       kCount,
186       kFieldsCount
187     };
188
189     uint32_t fields_[kFieldsCount];
190
191     DISALLOW_COPY_AND_ASSIGN(AsyncListener);
192   };
193
194   class TickInfo {
195    public:
196     inline uint32_t* fields();
197     inline int fields_count() const;
198     inline bool in_tick() const;
199     inline bool last_threw() const;
200     inline uint32_t index() const;
201     inline uint32_t length() const;
202     inline void set_in_tick(bool value);
203     inline void set_index(uint32_t value);
204     inline void set_last_threw(bool value);
205
206    private:
207     friend class Environment;  // So we can call the constructor.
208     inline TickInfo();
209
210     enum Fields {
211       kIndex,
212       kLength,
213       kFieldsCount
214     };
215
216     uint32_t fields_[kFieldsCount];
217     bool in_tick_;
218     bool last_threw_;
219
220     DISALLOW_COPY_AND_ASSIGN(TickInfo);
221   };
222
223   static inline Environment* GetCurrent(v8::Isolate* isolate);
224   static inline Environment* GetCurrent(v8::Local<v8::Context> context);
225   static inline Environment* GetCurrentChecked(v8::Isolate* isolate);
226   static inline Environment* GetCurrentChecked(v8::Local<v8::Context> context);
227
228   // See CreateEnvironment() in src/node.cc.
229   static inline Environment* New(v8::Local<v8::Context> context);
230   inline void Dispose();
231
232   inline v8::Isolate* isolate() const;
233   inline uv_loop_t* event_loop() const;
234   inline bool has_async_listeners() const;
235
236   static inline Environment* from_immediate_check_handle(uv_check_t* handle);
237   inline uv_check_t* immediate_check_handle();
238   inline uv_idle_t* immediate_idle_handle();
239
240   static inline Environment* from_idle_prepare_handle(uv_prepare_t* handle);
241   inline uv_prepare_t* idle_prepare_handle();
242
243   static inline Environment* from_idle_check_handle(uv_check_t* handle);
244   inline uv_check_t* idle_check_handle();
245
246   inline AsyncListener* async_listener();
247   inline TickInfo* tick_info();
248
249   static inline Environment* from_cares_timer_handle(uv_timer_t* handle);
250   inline uv_timer_t* cares_timer_handle();
251   inline ares_channel cares_channel();
252   inline ares_channel* cares_channel_ptr();
253   inline ares_task_list* cares_task_list();
254
255   inline bool using_smalloc_alloc_cb() const;
256   inline void set_using_smalloc_alloc_cb(bool value);
257
258   // Strings are shared across shared contexts. The getters simply proxy to
259   // the per-isolate primitive.
260 #define V(PropertyName, StringValue)                                          \
261   inline v8::Local<v8::String> PropertyName() const;
262   PER_ISOLATE_STRING_PROPERTIES(V)
263 #undef V
264
265 #define V(PropertyName, TypeName)                                             \
266   inline v8::Local<TypeName> PropertyName() const;                            \
267   inline void set_ ## PropertyName(v8::Local<TypeName> value);
268   ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
269 #undef V
270
271  private:
272   class IsolateData;
273   inline explicit Environment(v8::Local<v8::Context> context);
274   inline ~Environment();
275   inline IsolateData* isolate_data() const;
276
277   enum ContextEmbedderDataIndex {
278     kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX
279   };
280
281   v8::Isolate* const isolate_;
282   IsolateData* const isolate_data_;
283   uv_check_t immediate_check_handle_;
284   uv_idle_t immediate_idle_handle_;
285   uv_prepare_t idle_prepare_handle_;
286   uv_check_t idle_check_handle_;
287   AsyncListener async_listener_count_;
288   TickInfo tick_info_;
289   uv_timer_t cares_timer_handle_;
290   ares_channel cares_channel_;
291   ares_task_list cares_task_list_;
292   bool using_smalloc_alloc_cb_;
293
294 #define V(PropertyName, TypeName)                                             \
295   v8::Persistent<TypeName> PropertyName ## _;
296   ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
297 #undef V
298
299   // Per-thread, reference-counted singleton.
300   class IsolateData {
301    public:
302     static inline IsolateData* GetOrCreate(v8::Isolate* isolate);
303     inline void Put();
304     inline uv_loop_t* event_loop() const;
305
306 #define V(PropertyName, StringValue)                                          \
307     inline v8::Local<v8::String> PropertyName() const;
308     PER_ISOLATE_STRING_PROPERTIES(V)
309 #undef V
310
311    private:
312     inline explicit IsolateData(v8::Isolate* isolate);
313     inline v8::Isolate* isolate() const;
314
315     uv_loop_t* const event_loop_;
316     v8::Isolate* const isolate_;
317
318 #define V(PropertyName, StringValue)                                          \
319     v8::Eternal<v8::String> PropertyName ## _;
320     PER_ISOLATE_STRING_PROPERTIES(V)
321 #undef V
322
323     unsigned int ref_count_;
324
325     DISALLOW_COPY_AND_ASSIGN(IsolateData);
326   };
327
328   DISALLOW_COPY_AND_ASSIGN(Environment);
329 };
330
331 }  // namespace node
332
333 #endif  // SRC_ENV_H_