26
26
#include < node_isolate.h>
27
27
#include < node_internals.h>
28
28
#include < node_object_wrap.h>
29
+ #include < tcp_wrap.h>
29
30
30
31
#include < stdlib.h>
31
32
#include < string.h>
34
35
35
36
#define isolate_debugger_constructor NODE_VAR (isolate_debugger_constructor)
36
37
38
+ #define ISOLATEMESSAGE_SHARED_STREAM 0x0001
39
+
37
40
38
41
namespace node {
39
42
@@ -166,23 +169,35 @@ class Channel {
166
169
167
170
168
171
struct IsolateMessage {
169
- size_t size_;
170
- char * data_;
172
+ int flags;
173
+ struct {
174
+ size_t size_;
175
+ char * buffer_;
176
+ } data_;
177
+ uv_stream_info_t shared_stream_info_;
178
+
179
+ IsolateMessage (const char * buffer, size_t size,
180
+ uv_stream_info_t * shared_stream_info) {
181
+ flags = 0 ;
171
182
172
- IsolateMessage (const char * data, size_t size) {
173
183
// make a copy for now
174
- size_ = size;
175
- data_ = new char [size];
176
- memcpy (data_, data, size);
184
+ data_.size_ = size;
185
+ data_.buffer_ = new char [size];
186
+ memcpy (data_.buffer_ , buffer, size);
187
+
188
+ if (shared_stream_info) {
189
+ flags |= ISOLATEMESSAGE_SHARED_STREAM;
190
+ shared_stream_info_ = *shared_stream_info;
191
+ }
177
192
}
178
193
179
194
~IsolateMessage () {
180
- delete[] data_;
195
+ delete[] data_. buffer_ ;
181
196
}
182
197
183
198
static void Free (char * data, void * arg) {
184
199
IsolateMessage* msg = static_cast <IsolateMessage*>(arg);
185
- assert (data == msg->data_ );
200
+ assert (data == msg->data_ . buffer_ );
186
201
delete msg;
187
202
}
188
203
};
@@ -208,7 +223,23 @@ Handle<Value> Isolate::Send(const Arguments& args) {
208
223
const char * data = Buffer::Data (obj);
209
224
size_t size = Buffer::Length (obj);
210
225
211
- IsolateMessage* msg = new IsolateMessage (data, size);
226
+ IsolateMessage* msg;
227
+
228
+ if (args[1 ]->IsObject ()) {
229
+ uv_stream_info_t stream_info;
230
+
231
+ Local<Object> send_stream_obj = args[1 ]->ToObject ();
232
+ assert (send_stream_obj->InternalFieldCount () > 0 );
233
+ StreamWrap* send_stream_wrap = static_cast <StreamWrap*>(
234
+ send_stream_obj->GetPointerFromInternalField (0 ));
235
+ uv_stream_t * send_stream = send_stream_wrap->GetStream ();
236
+ int r = uv_export (send_stream, &stream_info);
237
+ assert (r == 0 );
238
+ msg = new IsolateMessage (data, size, &stream_info);
239
+ } else {
240
+ msg = new IsolateMessage (data, size, NULL );
241
+ }
242
+
212
243
isolate->send_channel_ ->Send (msg);
213
244
214
245
return Undefined ();
@@ -231,9 +262,31 @@ void Isolate::OnMessage(IsolateMessage* msg, void* arg) {
231
262
Isolate* self = static_cast <Isolate*>(arg);
232
263
NODE_ISOLATE_CHECK (self);
233
264
234
- Buffer* buf = Buffer::New (msg->data_ , msg->size_ , IsolateMessage::Free, msg);
235
- Handle <Value> argv[] = { buf->handle_ };
236
- MakeCallback (self->globals_ .process , " _onmessage" , ARRAY_SIZE (argv), argv);
265
+ Buffer* buf = Buffer::New (msg->data_ .buffer_ , msg->data_ .size_ ,
266
+ IsolateMessage::Free, msg);
267
+
268
+ int argc = 1 ;
269
+ Handle <Value> argv[2 ] = {
270
+ buf->handle_
271
+ };
272
+
273
+ if (msg->flags & ISOLATEMESSAGE_SHARED_STREAM) {
274
+ // Instantiate the client javascript object and handle.
275
+ Local<Object> pending_obj = TCPWrap::Instantiate ();
276
+
277
+ // Unwrap the client javascript object.
278
+ assert (pending_obj->InternalFieldCount () > 0 );
279
+ TCPWrap* pending_wrap =
280
+ static_cast <TCPWrap*>(pending_obj->GetPointerFromInternalField (0 ));
281
+
282
+ int r = uv_import (pending_wrap->GetStream (), &msg->shared_stream_info_ );
283
+ assert (r == 0 );
284
+
285
+ argv[1 ] = pending_obj;
286
+ argc++;
287
+ }
288
+
289
+ MakeCallback (self->globals_ .process , " _onmessage" , argc, argv);
237
290
}
238
291
239
292
@@ -442,9 +495,30 @@ struct IsolateWrap: public ObjectWrap {
442
495
NODE_ISOLATE_CHECK (parent_isolate_);
443
496
HandleScope scope;
444
497
Buffer* buf = Buffer::New (
445
- msg->data_ , msg->size_ , IsolateMessage::Free, msg);
446
- Handle <Value> argv[] = { buf->handle_ };
447
- MakeCallback (handle_, " onmessage" , ARRAY_SIZE (argv), argv);
498
+ msg->data_ .buffer_ , msg->data_ .size_ , IsolateMessage::Free, msg);
499
+
500
+ int argc = 1 ;
501
+ Handle <Value> argv[2 ] = {
502
+ buf->handle_
503
+ };
504
+
505
+ if (msg->flags & ISOLATEMESSAGE_SHARED_STREAM) {
506
+ // Instantiate the client javascript object and handle.
507
+ Local<Object> pending_obj = TCPWrap::Instantiate ();
508
+
509
+ // Unwrap the client javascript object.
510
+ assert (pending_obj->InternalFieldCount () > 0 );
511
+ TCPWrap* pending_wrap =
512
+ static_cast <TCPWrap*>(pending_obj->GetPointerFromInternalField (0 ));
513
+
514
+ int r = uv_import (pending_wrap->GetStream (), &msg->shared_stream_info_ );
515
+ assert (r == 0 );
516
+
517
+ argv[1 ] = pending_obj;
518
+ argc++;
519
+ }
520
+
521
+ MakeCallback (handle_, " onmessage" , argc, argv);
448
522
}
449
523
450
524
// TODO merge with Isolate::Send(), it's almost identical
@@ -457,9 +531,24 @@ struct IsolateWrap: public ObjectWrap {
457
531
const char * data = Buffer::Data (obj);
458
532
size_t size = Buffer::Length (obj);
459
533
460
- IsolateMessage* msg = new IsolateMessage (data, size);
461
- self->send_channel_ ->Send (msg);
534
+ IsolateMessage* msg;
535
+
536
+ if (args[1 ]->IsObject ()) {
537
+ uv_stream_info_t stream_info;
538
+
539
+ Local<Object> send_stream_obj = args[1 ]->ToObject ();
540
+ assert (send_stream_obj->InternalFieldCount () > 0 );
541
+ StreamWrap* send_stream_wrap = static_cast <StreamWrap*>(
542
+ send_stream_obj->GetPointerFromInternalField (0 ));
543
+ uv_stream_t * send_stream = send_stream_wrap->GetStream ();
544
+ int r = uv_export (send_stream, &stream_info);
545
+ assert (r == 0 );
546
+ msg = new IsolateMessage (data, size, &stream_info);
547
+ } else {
548
+ msg = new IsolateMessage (data, size, NULL );
549
+ }
462
550
551
+ self->send_channel_ ->Send (msg);
463
552
return Undefined ();
464
553
}
465
554
0 commit comments