summaryrefslogtreecommitdiff
path: root/src/env.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/env.h')
-rw-r--r--src/env.h324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/env.h b/src/env.h
new file mode 100644
index 0000000000..db8d660c30
--- /dev/null
+++ b/src/env.h
@@ -0,0 +1,324 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SRC_ENV_H_
+#define SRC_ENV_H_
+
+#include "ares.h"
+#include "tree.h"
+#include "util.h"
+#include "uv.h"
+#include "v8.h"
+
+#include <stdint.h>
+
+// Caveat emptor: we're going slightly crazy with macros here but the end
+// hopefully justifies the means. We have a lot of per-context properties
+// and adding and maintaining their getters and setters by hand would be
+// a nightmare so let's make the preprocessor generate them for us.
+//
+// Make sure that any macros defined here are undefined again at the bottom
+// of context-inl.h. The sole exception is NODE_CONTEXT_EMBEDDER_DATA_INDEX,
+// it may have been defined externally.
+namespace node {
+
+// Pick an index that's hopefully out of the way when we're embedded inside
+// another application. Performance-wise or memory-wise it doesn't matter:
+// Context::SetAlignedPointerInEmbedderData() is backed by a FixedArray,
+// worst case we pay a one-time penalty for resizing the array.
+#ifndef NODE_CONTEXT_EMBEDDER_DATA_INDEX
+#define NODE_CONTEXT_EMBEDDER_DATA_INDEX 32
+#endif
+
+// Strings are per-isolate primitives but Environment proxies them
+// for the sake of convenience.
+#define PER_ISOLATE_STRING_PROPERTIES(V) \
+ V(DELETE_string, "DELETE") \
+ V(GET_string, "GET") \
+ V(HEAD_string, "HEAD") \
+ V(POST_string, "POST") \
+ V(PUT_string, "PUT") \
+ V(address_string, "address") \
+ V(atime_string, "atime") \
+ V(birthtime_string, "birthtime") \
+ V(blksize_string, "blksize") \
+ V(blocks_string, "blocks") \
+ V(buffer_string, "buffer") \
+ V(bytes_string, "bytes") \
+ V(callback_string, "callback") \
+ V(change_string, "change") \
+ V(close_string, "close") \
+ V(code_string, "code") \
+ V(ctime_string, "ctime") \
+ V(dev_string, "dev") \
+ V(disposed_string, "_disposed") \
+ V(domain_string, "domain") \
+ V(enter_string, "enter") \
+ V(errno_string, "errno") \
+ V(exit_string, "exit") \
+ V(exponent_string, "exponent") \
+ V(exports_string, "exports") \
+ V(ext_key_usage_string, "ext_key_usage") \
+ V(family_string, "family") \
+ V(fatal_exception_string, "_fatalException") \
+ V(fingerprint_string, "fingerprint") \
+ V(gid_string, "gid") \
+ V(handle_string, "handle") \
+ V(headers_string, "headers") \
+ V(heap_total_string, "heapTotal") \
+ V(heap_used_string, "heapUsed") \
+ V(immediate_callback_string, "_immediateCallback") \
+ V(ino_string, "ino") \
+ V(ipv4_string, "IPv4") \
+ V(ipv6_string, "IPv6") \
+ V(issuer_string, "issuer") \
+ V(method_string, "method") \
+ V(mode_string, "mode") \
+ V(modulus_string, "modulus") \
+ V(mtime_string, "mtime") \
+ V(name_string, "name") \
+ V(nlink_string, "nlink") \
+ V(onchange_string, "onchange") \
+ V(onclienthello_string, "onclienthello") \
+ V(oncomplete_string, "oncomplete") \
+ V(onconnection_string, "onconnection") \
+ V(onerror_string, "onerror") \
+ V(onexit_string, "onexit") \
+ V(onhandshakedone_string, "onhandshakedone") \
+ V(onhandshakestart_string, "onhandshakestart") \
+ V(onmessage_string, "onmessage") \
+ V(onnewsession_string, "onnewsession") \
+ V(onread_string, "onread") \
+ V(onsignal_string, "onsignal") \
+ V(onstop_string, "onstop") \
+ V(path_string, "path") \
+ V(port_string, "port") \
+ V(rdev_string, "rdev") \
+ V(rename_string, "rename") \
+ V(rss_string, "rss") \
+ V(servername_string, "servername") \
+ V(session_id_string, "sessionId") \
+ V(should_keep_alive_string, "shouldKeepAlive") \
+ V(size_string, "size") \
+ V(smalloc_p_string, "_smalloc_p") \
+ V(sni_context_string, "sni_context") \
+ V(status_code_string, "statusCode") \
+ V(subject_string, "subject") \
+ V(subjectaltname_string, "subjectaltname") \
+ V(syscall_string, "syscall") \
+ V(tls_ticket_string, "tlsTicket") \
+ V(uid_string, "uid") \
+ V(upgrade_string, "upgrade") \
+ V(url_string, "url") \
+ V(valid_from_string, "valid_from") \
+ V(valid_to_string, "valid_to") \
+ V(version_major_string, "versionMajor") \
+ V(version_minor_string, "versionMinor") \
+ V(version_string, "version") \
+ V(write_queue_size_string, "writeQueueSize") \
+
+#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \
+ V(binding_cache_object, v8::Object) \
+ V(buffer_constructor_function, v8::Function) \
+ V(context, v8::Context) \
+ V(domain_array, v8::Array) \
+ V(module_load_list_array, v8::Array) \
+ V(pipe_constructor_template, v8::FunctionTemplate) \
+ V(process_object, v8::Object) \
+ V(script_context_constructor_template, v8::FunctionTemplate) \
+ V(script_data_constructor_function, v8::Function) \
+ V(secure_context_constructor_template, v8::FunctionTemplate) \
+ V(stats_constructor_function, v8::Function) \
+ V(tcp_constructor_template, v8::FunctionTemplate) \
+ V(tick_callback_function, v8::Function) \
+ V(tls_wrap_constructor_function, v8::Function) \
+ V(tty_constructor_template, v8::FunctionTemplate) \
+ V(udp_constructor_function, v8::Function) \
+
+class Environment;
+
+// TODO(bnoordhuis) Rename struct, the ares_ prefix implies it's part
+// of the c-ares API while the _t suffix implies it's a typedef.
+struct ares_task_t {
+ Environment* env;
+ ares_socket_t sock;
+ uv_poll_t poll_watcher;
+ RB_ENTRY(ares_task_t) node;
+};
+
+RB_HEAD(ares_task_list, ares_task_t);
+
+class Environment {
+ public:
+ class DomainFlag {
+ public:
+ inline uint32_t* fields();
+ inline int fields_count() const;
+ inline uint32_t count() const;
+
+ private:
+ friend class Environment; // So we can call the constructor.
+ inline DomainFlag();
+
+ enum Fields {
+ kCount,
+ kFieldsCount
+ };
+
+ uint32_t fields_[kFieldsCount];
+
+ DISALLOW_COPY_AND_ASSIGN(DomainFlag);
+ };
+
+ class TickInfo {
+ public:
+ inline uint32_t* fields();
+ inline int fields_count() const;
+ inline uint32_t in_tick() const;
+ inline uint32_t index() const;
+ inline uint32_t last_threw() const;
+ inline uint32_t length() const;
+ inline void set_index(uint32_t value);
+ inline void set_last_threw(uint32_t value);
+
+ private:
+ friend class Environment; // So we can call the constructor.
+ inline TickInfo();
+
+ enum Fields {
+ kInTick,
+ kIndex,
+ kLastThrew,
+ kLength,
+ kFieldsCount
+ };
+
+ uint32_t fields_[kFieldsCount];
+
+ DISALLOW_COPY_AND_ASSIGN(TickInfo);
+ };
+
+ static inline Environment* GetCurrent(v8::Isolate* isolate);
+ static inline Environment* GetCurrent(v8::Local<v8::Context> context);
+ static inline Environment* GetCurrentChecked(v8::Isolate* isolate);
+ static inline Environment* GetCurrentChecked(v8::Local<v8::Context> context);
+
+ // See CreateEnvironment() in src/node.cc.
+ static inline Environment* New(v8::Local<v8::Context> context);
+ inline void Dispose();
+
+ inline v8::Isolate* isolate() const;
+ inline uv_loop_t* event_loop() const;
+ inline bool in_domain() const;
+
+ static inline Environment* from_immediate_check_handle(uv_check_t* handle);
+ inline uv_check_t* immediate_check_handle();
+ inline uv_idle_t* immediate_idle_handle();
+ inline DomainFlag* domain_flag();
+ inline TickInfo* tick_info();
+
+ static inline Environment* from_cares_timer_handle(uv_timer_t* handle);
+ inline uv_timer_t* cares_timer_handle();
+ inline ares_channel cares_channel();
+ inline ares_channel* cares_channel_ptr();
+ inline ares_task_list* cares_task_list();
+
+ inline bool using_smalloc_alloc_cb() const;
+ inline void set_using_smalloc_alloc_cb(bool value);
+
+ inline bool using_domains() const;
+ inline void set_using_domains(bool value);
+
+ // Strings are shared across shared contexts. The getters simply proxy to
+ // the per-isolate primitive.
+#define V(PropertyName, StringValue) \
+ inline v8::Local<v8::String> PropertyName() const;
+ PER_ISOLATE_STRING_PROPERTIES(V)
+#undef V
+
+#define V(PropertyName, TypeName) \
+ inline v8::Local<TypeName> PropertyName() const; \
+ inline void set_ ## PropertyName(v8::Local<TypeName> value);
+ ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
+#undef V
+
+ private:
+ class IsolateData;
+ inline explicit Environment(v8::Local<v8::Context> context);
+ inline ~Environment();
+ inline IsolateData* isolate_data() const;
+
+ enum ContextEmbedderDataIndex {
+ kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX
+ };
+
+ v8::Isolate* const isolate_;
+ IsolateData* const isolate_data_;
+ uv_check_t immediate_check_handle_;
+ uv_idle_t immediate_idle_handle_;
+ DomainFlag domain_flag_;
+ TickInfo tick_info_;
+ uv_timer_t cares_timer_handle_;
+ ares_channel cares_channel_;
+ ares_task_list cares_task_list_;
+ bool using_smalloc_alloc_cb_;
+ bool using_domains_;
+
+#define V(PropertyName, TypeName) \
+ v8::Persistent<TypeName> PropertyName ## _;
+ ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
+#undef V
+
+ // Per-thread, reference-counted singleton.
+ class IsolateData {
+ public:
+ static inline IsolateData* GetOrCreate(v8::Isolate* isolate);
+ inline void Put();
+ inline uv_loop_t* event_loop() const;
+
+#define V(PropertyName, StringValue) \
+ inline v8::Local<v8::String> PropertyName() const;
+ PER_ISOLATE_STRING_PROPERTIES(V)
+#undef V
+
+ private:
+ inline explicit IsolateData(v8::Isolate* isolate);
+ inline v8::Isolate* isolate() const;
+
+ uv_loop_t* const event_loop_;
+ v8::Isolate* const isolate_;
+
+#define V(PropertyName, StringValue) \
+ const int PropertyName ## _index_;
+ PER_ISOLATE_STRING_PROPERTIES(V)
+#undef V
+
+ unsigned int ref_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(IsolateData);
+ };
+
+ DISALLOW_COPY_AND_ASSIGN(Environment);
+};
+
+} // namespace node
+
+#endif // SRC_ENV_H_