Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: runtime/vm/service.cc

Issue 170943003: Allow for embedder provided service request handlers (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« runtime/include/dart_api.h ('K') | « runtime/vm/service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/service.h" 5 #include "vm/service.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/coverage.h" 10 #include "vm/coverage.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 97
98 static ResourcesEntry* ResourceTable() { 98 static ResourcesEntry* ResourceTable() {
99 return &__service_resources_[0]; 99 return &__service_resources_[0];
100 } 100 }
101 101
102 DISALLOW_ALLOCATION(); 102 DISALLOW_ALLOCATION();
103 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources); 103 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
104 }; 104 };
105 105
106 106
107 class EmbedderServiceHandler {
108 public:
109 explicit EmbedderServiceHandler(const char* name) : name_(NULL),
110 callback_(NULL),
111 user_data_(NULL),
112 next_(NULL) {
113 ASSERT(name != NULL);
114 name_ = strdup(name);
115 }
116
117 ~EmbedderServiceHandler() {
118 free(name_);
119 }
120
121 const char* name() const { return name_; }
122
123 Dart_ServiceRequestCallback callback() const { return callback_; }
124 void set_callback(Dart_ServiceRequestCallback callback) {
125 callback_ = callback;
126 }
127
128 void* user_data() const { return user_data_; }
129 void set_user_data(void* user_data) {
130 user_data_ = user_data;
131 }
132
133 EmbedderServiceHandler* next() const { return next_; }
134 void set_next(EmbedderServiceHandler* next) {
135 next_ = next;
136 }
137
138 private:
139 char* name_;
140 Dart_ServiceRequestCallback callback_;
141 void* user_data_;
142 EmbedderServiceHandler* next_;
143 };
144
145
107 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 146 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
108 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 147 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
109 return reinterpret_cast<uint8_t*>(new_ptr); 148 return reinterpret_cast<uint8_t*>(new_ptr);
110 } 149 }
111 150
112 151
113 static void SendIsolateServiceMessage(Dart_NativeArguments args) { 152 static void SendIsolateServiceMessage(Dart_NativeArguments args) {
114 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 153 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
115 Isolate* isolate = arguments->isolate(); 154 Isolate* isolate = arguments->isolate();
116 StackZone zone(isolate); 155 StackZone zone(isolate);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; 218 VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
180 if (!strcmp(function_name, entry.name) && 219 if (!strcmp(function_name, entry.name) &&
181 (num_arguments == entry.num_arguments)) { 220 (num_arguments == entry.num_arguments)) {
182 return entry.function; 221 return entry.function;
183 } 222 }
184 } 223 }
185 return NULL; 224 return NULL;
186 } 225 }
187 226
188 227
228 EmbedderServiceHandler* Service::service_handler_head_ = NULL;
189 Isolate* Service::service_isolate_ = NULL; 229 Isolate* Service::service_isolate_ = NULL;
190 Dart_LibraryTagHandler Service::default_handler_ = NULL; 230 Dart_LibraryTagHandler Service::default_handler_ = NULL;
191 Dart_Port Service::port_ = ILLEGAL_PORT; 231 Dart_Port Service::port_ = ILLEGAL_PORT;
192 232
233
193 static Dart_Port ExtractPort(Dart_Handle receivePort) { 234 static Dart_Port ExtractPort(Dart_Handle receivePort) {
194 HANDLESCOPE(Isolate::Current()); 235 HANDLESCOPE(Isolate::Current());
195 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort)); 236 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
196 const Instance& rp = Instance::Cast(unwrapped_rp); 237 const Instance& rp = Instance::Cast(unwrapped_rp);
197 // Extract RawReceivePort port id. 238 // Extract RawReceivePort port id.
198 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); 239 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
199 if (rp_id_obj.IsError()) { 240 if (rp_id_obj.IsError()) {
200 return ILLEGAL_PORT; 241 return ILLEGAL_PORT;
201 } 242 }
202 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); 243 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if (path.Length() > 0) { 558 if (path.Length() > 0) {
518 path_segment ^= path.At(0); 559 path_segment ^= path.At(0);
519 } else { 560 } else {
520 path_segment ^= Symbols::Empty().raw(); 561 path_segment ^= Symbols::Empty().raw();
521 } 562 }
522 ASSERT(!path_segment.IsNull()); 563 ASSERT(!path_segment.IsNull());
523 const char* path_segment_c = path_segment.ToCString(); 564 const char* path_segment_c = path_segment.ToCString();
524 565
525 IsolateMessageHandler handler = 566 IsolateMessageHandler handler =
526 FindIsolateMessageHandler(path_segment_c); 567 FindIsolateMessageHandler(path_segment_c);
568 if (handler == NULL) {
569 // Check for an embedder handler.
570 EmbedderServiceHandler* e_handler = FindEmbedderHandler(path_segment_c);
571 if (e_handler != NULL) {
572 JSONStream js;
573 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
574 EmbedderHandleIsolateMessage(e_handler, &js);
turnidge 2014/02/18 21:27:05 Do we want to allow for asynchronous replies? Sho
575 js.PostReply();
576 }
577 }
527 { 578 {
528 JSONStream js; 579 JSONStream js;
529 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); 580 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
530
531 if (handler == NULL) { 581 if (handler == NULL) {
532 PrintError(&js, "Unrecognized path"); 582 PrintError(&js, "Unrecognized path");
533 js.PostReply(); 583 js.PostReply();
534 } else { 584 } else {
535 if (handler(isolate, &js)) { 585 if (handler(isolate, &js)) {
536 // Handler returns true if the reply is ready to be posted. 586 // Handler returns true if the reply is ready to be posted.
537 js.PostReply(); 587 js.PostReply();
538 } 588 }
539 } 589 }
540 } 590 }
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 if (!strcmp(command, entry.command)) { 1199 if (!strcmp(command, entry.command)) {
1150 return entry.handler; 1200 return entry.handler;
1151 } 1201 }
1152 } 1202 }
1153 if (FLAG_trace_service) { 1203 if (FLAG_trace_service) {
1154 OS::Print("Service has no root message handler for <%s>\n", command); 1204 OS::Print("Service has no root message handler for <%s>\n", command);
1155 } 1205 }
1156 return NULL; 1206 return NULL;
1157 } 1207 }
1158 1208
1209
1210 void Service::EmbedderHandleIsolateMessage(EmbedderServiceHandler* handler,
1211 JSONStream* js) {
1212 ASSERT(handler != NULL);
1213 Dart_ServiceRequestCallback callback = handler->callback();
1214 ASSERT(callback != NULL);
1215 const char* r = NULL;
1216 const char* name = js->command();
1217 const char** arguments = js->arguments();
1218 const char** keys = js->option_keys();
1219 const char** values = js->option_values();
1220 r = callback(name, arguments, js->num_arguments(), keys, values,
1221 js->num_options(), handler->user_data());
1222 ASSERT(r != NULL);
1223 // TODO(johnmccutchan): Allow for NULL returns?
1224 TextBuffer* buffer = js->buffer();
1225 buffer->AddString(r);
1226 free(const_cast<char*>(r));
1227 }
1228
1229
1230 void Service::RegisterEmbedderCallback(const char* name,
1231 Dart_ServiceRequestCallback callback,
1232 void* user_data) {
turnidge 2014/02/18 21:27:05 Add a heartbeat unit test for embedder callbacks i
Cutch 2014/02/18 22:18:51 Done.
1233 if (name == NULL) {
1234 return;
1235 }
1236 EmbedderServiceHandler* handler = FindEmbedderHandler(name);
1237 if (handler != NULL) {
1238 // Update existing handler entry.
1239 handler->set_callback(callback);
1240 handler->set_user_data(user_data);
1241 return;
1242 }
1243 // Create a new handler.
1244 handler = new EmbedderServiceHandler(name);
1245 handler->set_callback(callback);
1246 handler->set_user_data(user_data);
1247
1248 // Insert into list.
1249 handler->set_next(service_handler_head_);
1250 service_handler_head_ = handler;
1251 }
1252
1253
1254 EmbedderServiceHandler* Service::FindEmbedderHandler(
1255 const char* name) {
1256 EmbedderServiceHandler* current = service_handler_head_;
1257 while (current != NULL) {
1258 if (!strcmp(name, current->name())) {
1259 return current;
1260 }
1261 }
1262 return NULL;
1263 }
1264
1265
1159 } // namespace dart 1266 } // namespace dart
OLDNEW
« runtime/include/dart_api.h ('K') | « runtime/vm/service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698