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

Unified 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 side-by-side diff with in-line comments
Download patch
« runtime/include/dart_api.h ('K') | « runtime/vm/service.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/service.cc
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 7596e7aab7f683d8eeaaef25bc719fbc61f5ee18..4288556070b0f8d14b725e08799d842bff0f7cd0 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -104,6 +104,45 @@ class Resources {
};
+class EmbedderServiceHandler {
+ public:
+ explicit EmbedderServiceHandler(const char* name) : name_(NULL),
+ callback_(NULL),
+ user_data_(NULL),
+ next_(NULL) {
+ ASSERT(name != NULL);
+ name_ = strdup(name);
+ }
+
+ ~EmbedderServiceHandler() {
+ free(name_);
+ }
+
+ const char* name() const { return name_; }
+
+ Dart_ServiceRequestCallback callback() const { return callback_; }
+ void set_callback(Dart_ServiceRequestCallback callback) {
+ callback_ = callback;
+ }
+
+ void* user_data() const { return user_data_; }
+ void set_user_data(void* user_data) {
+ user_data_ = user_data;
+ }
+
+ EmbedderServiceHandler* next() const { return next_; }
+ void set_next(EmbedderServiceHandler* next) {
+ next_ = next;
+ }
+
+ private:
+ char* name_;
+ Dart_ServiceRequestCallback callback_;
+ void* user_data_;
+ EmbedderServiceHandler* next_;
+};
+
+
static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
return reinterpret_cast<uint8_t*>(new_ptr);
@@ -186,10 +225,12 @@ static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
}
+EmbedderServiceHandler* Service::service_handler_head_ = NULL;
Isolate* Service::service_isolate_ = NULL;
Dart_LibraryTagHandler Service::default_handler_ = NULL;
Dart_Port Service::port_ = ILLEGAL_PORT;
+
static Dart_Port ExtractPort(Dart_Handle receivePort) {
HANDLESCOPE(Isolate::Current());
const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
@@ -524,10 +565,19 @@ void Service::HandleIsolateMessage(Isolate* isolate, const Instance& msg) {
IsolateMessageHandler handler =
FindIsolateMessageHandler(path_segment_c);
+ if (handler == NULL) {
+ // Check for an embedder handler.
+ EmbedderServiceHandler* e_handler = FindEmbedderHandler(path_segment_c);
+ if (e_handler != NULL) {
+ JSONStream js;
+ js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
+ EmbedderHandleIsolateMessage(e_handler, &js);
turnidge 2014/02/18 21:27:05 Do we want to allow for asynchronous replies? Sho
+ js.PostReply();
+ }
+ }
{
JSONStream js;
js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values);
-
if (handler == NULL) {
PrintError(&js, "Unrecognized path");
js.PostReply();
@@ -1156,4 +1206,61 @@ static RootMessageHandler FindRootMessageHandler(const char* command) {
return NULL;
}
+
+void Service::EmbedderHandleIsolateMessage(EmbedderServiceHandler* handler,
+ JSONStream* js) {
+ ASSERT(handler != NULL);
+ Dart_ServiceRequestCallback callback = handler->callback();
+ ASSERT(callback != NULL);
+ const char* r = NULL;
+ const char* name = js->command();
+ const char** arguments = js->arguments();
+ const char** keys = js->option_keys();
+ const char** values = js->option_values();
+ r = callback(name, arguments, js->num_arguments(), keys, values,
+ js->num_options(), handler->user_data());
+ ASSERT(r != NULL);
+ // TODO(johnmccutchan): Allow for NULL returns?
+ TextBuffer* buffer = js->buffer();
+ buffer->AddString(r);
+ free(const_cast<char*>(r));
+}
+
+
+void Service::RegisterEmbedderCallback(const char* name,
+ Dart_ServiceRequestCallback callback,
+ 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.
+ if (name == NULL) {
+ return;
+ }
+ EmbedderServiceHandler* handler = FindEmbedderHandler(name);
+ if (handler != NULL) {
+ // Update existing handler entry.
+ handler->set_callback(callback);
+ handler->set_user_data(user_data);
+ return;
+ }
+ // Create a new handler.
+ handler = new EmbedderServiceHandler(name);
+ handler->set_callback(callback);
+ handler->set_user_data(user_data);
+
+ // Insert into list.
+ handler->set_next(service_handler_head_);
+ service_handler_head_ = handler;
+}
+
+
+EmbedderServiceHandler* Service::FindEmbedderHandler(
+ const char* name) {
+ EmbedderServiceHandler* current = service_handler_head_;
+ while (current != NULL) {
+ if (!strcmp(name, current->name())) {
+ return current;
+ }
+ }
+ return NULL;
+}
+
+
} // namespace dart
« 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