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

Side by Side Diff: runtime/bin/vmstats_impl.cc

Issue 12316148: Quick fix for racy shutdown issues in VmStats. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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
« no previous file with comments | « runtime/bin/vmstats_impl.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 "bin/vmstats_impl.h" 5 #include "bin/vmstats_impl.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "bin/file.h" 9 #include "bin/file.h"
10 #include "bin/log.h" 10 #include "bin/log.h"
11 #include "bin/platform.h" 11 #include "bin/platform.h"
12 #include "bin/socket.h" 12 #include "bin/socket.h"
13 #include "bin/thread.h" 13 #include "bin/thread.h"
14 #include "bin/utils.h" 14 #include "bin/utils.h"
15 #include "include/dart_debugger_api.h" 15 #include "include/dart_debugger_api.h"
16 #include "platform/json.h" 16 #include "platform/json.h"
17 17
18 #define BUFSIZE 8192 18 #define BUFSIZE 8192
19 #define RETRY_PAUSE 100 // milliseconds 19 #define RETRY_PAUSE 100 // milliseconds
20 20
21 static const char* INDEX_HTML = "index.html"; 21 static const char* INDEX_HTML = "index.html";
22 static const char* VMSTATS_HTML = "vmstats.html"; 22 static const char* VMSTATS_HTML = "vmstats.html";
23 static const char* DEFAULT_HOST = "localhost"; 23 static const char* DEFAULT_HOST = "localhost";
24 24
25 // Global static pointer used to ensure a single instance of the class. 25 // Global static pointer used to ensure a single instance of the class.
26 VmStats* VmStats::instance_ = NULL; 26 VmStats* VmStats::instance_ = NULL;
27 dart::Monitor VmStats::instance_monitor_; 27 dart::Monitor* VmStats::instance_monitor_;
28 dart::Mutex VmStatusService::mutex_; 28 dart::Mutex* VmStatusService::mutex_;
29 29
30 30
31 void VmStats::Start(int port, const char* root_dir) { 31 void VmStats::Start(int port, const char* root_dir) {
32 if (instance_ != NULL) { 32 if (instance_ != NULL) {
33 FATAL("VmStats already started."); 33 FATAL("VmStats already started.");
34 } 34 }
35 MonitorLocker ml(&instance_monitor_);
36 instance_ = new VmStats(); 35 instance_ = new VmStats();
36 instance_monitor_ = new dart::Monitor();
37 VmStatusService::InitOnce(); 37 VmStatusService::InitOnce();
38 Socket::Initialize(); 38 Socket::Initialize();
39 39
40 if (root_dir != NULL) { 40 if (root_dir != NULL) {
41 instance_->root_directory_ = root_dir; 41 instance_->root_directory_ = root_dir;
42 } 42 }
43 43
44 // TODO(tball): allow host to be specified. 44 // TODO(tball): allow host to be specified.
45 char* host = const_cast<char*>(DEFAULT_HOST); 45 char* host = const_cast<char*>(DEFAULT_HOST);
46 OSError* os_error; 46 OSError* os_error;
47 const char* host_ip = Socket::LookupIPv4Address(host, &os_error); 47 const char* host_ip = Socket::LookupIPv4Address(host, &os_error);
48 if (host_ip == NULL) { 48 if (host_ip == NULL) {
49 Log::PrintErr("Failed IP lookup of VmStats host %s: %s\n", 49 Log::PrintErr("Failed IP lookup of VmStats host %s: %s\n",
50 host, os_error->message()); 50 host, os_error->message());
51 return; 51 return;
52 } 52 }
53 53
54 const intptr_t BACKLOG = 128; // Default value from HttpServer.dart 54 const intptr_t BACKLOG = 128; // Default value from HttpServer.dart
55 int64_t address = ServerSocket::CreateBindListen(host_ip, port, BACKLOG); 55 int64_t address = ServerSocket::CreateBindListen(host_ip, port, BACKLOG);
56 if (address < 0) { 56 if (address < 0) {
57 Log::PrintErr("Failed binding VmStats socket: %s:%d\n", host, port); 57 Log::PrintErr("Failed binding VmStats socket: %s:%d\n", host, port);
58 return; 58 return;
59 } 59 }
60 instance_->bind_address_ = address; 60 instance_->bind_address_ = address;
61 Log::Print("VmStats URL: http://%s:%"Pd"/\n", host, Socket::GetPort(address)); 61 Log::Print("VmStats URL: http://%s:%"Pd"/\n", host, Socket::GetPort(address));
62 62
63 MonitorLocker ml(instance_monitor_);
63 instance_->running_ = true; 64 instance_->running_ = true;
64 int err = dart::Thread::Start(WebServer, address); 65 int err = dart::Thread::Start(WebServer, address);
65 if (err != 0) { 66 if (err != 0) {
66 Log::PrintErr("Failed starting VmStats thread: %d\n", err); 67 Log::PrintErr("Failed starting VmStats thread: %d\n", err);
67 Shutdown(); 68 Shutdown();
68 } 69 }
69 } 70 }
70 71
71 72
72 void VmStats::Stop() { 73 void VmStats::Stop() {
73 MonitorLocker ml(&instance_monitor_); 74 ASSERT(instance_ != NULL);
74 if (instance_ != NULL) { 75 MonitorLocker ml(instance_monitor_);
75 instance_->running_ = false; 76 instance_->running_ = false;
76 }
77 } 77 }
78 78
79 79
80 void VmStats::Shutdown() { 80 void VmStats::Shutdown() {
81 MonitorLocker ml(&instance_monitor_); 81 ASSERT(instance_ != NULL);
82 MonitorLocker ml(instance_monitor_);
82 Socket::Close(instance_->bind_address_); 83 Socket::Close(instance_->bind_address_);
83 delete instance_; 84 delete instance_;
84 instance_ = NULL; 85 instance_ = NULL;
85 } 86 }
86 87
87 88
88 void VmStats::AddIsolate(IsolateData* isolate_data, 89 void VmStats::AddIsolate(IsolateData* isolate_data,
89 Dart_Isolate isolate) { 90 Dart_Isolate isolate) {
90 MonitorLocker ml(&instance_monitor_);
91 if (instance_ != NULL) { 91 if (instance_ != NULL) {
92 MonitorLocker ml(instance_monitor_);
92 instance_->isolate_table_[isolate_data] = isolate; 93 instance_->isolate_table_[isolate_data] = isolate;
93 } 94 }
94 } 95 }
95 96
96 97
97 void VmStats::RemoveIsolate(IsolateData* isolate_data) { 98 void VmStats::RemoveIsolate(IsolateData* isolate_data) {
98 MonitorLocker ml(&instance_monitor_);
99 if (instance_ != NULL) { 99 if (instance_ != NULL) {
100 MonitorLocker ml(instance_monitor_);
100 instance_->isolate_table_.erase(isolate_data); 101 instance_->isolate_table_.erase(isolate_data);
101 } 102 }
102 } 103 }
103 104
104 105
105 static const char* ContentType(const char* url) { 106 static const char* ContentType(const char* url) {
106 const char* suffix = strrchr(url, '.'); 107 const char* suffix = strrchr(url, '.');
107 if (suffix != NULL) { 108 if (suffix != NULL) {
108 if (!strcmp(suffix, ".html")) { 109 if (!strcmp(suffix, ".html")) {
109 return "text/html; charset=UTF-8"; 110 return "text/html; charset=UTF-8";
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 288 }
288 289
289 290
290 // Global static pointer used to ensure a single instance of the class. 291 // Global static pointer used to ensure a single instance of the class.
291 VmStatusService* VmStatusService::instance_ = NULL; 292 VmStatusService* VmStatusService::instance_ = NULL;
292 293
293 294
294 void VmStatusService::InitOnce() { 295 void VmStatusService::InitOnce() {
295 ASSERT(VmStatusService::instance_ == NULL); 296 ASSERT(VmStatusService::instance_ == NULL);
296 VmStatusService::instance_ = new VmStatusService(); 297 VmStatusService::instance_ = new VmStatusService();
298 VmStatusService::mutex_ = new dart::Mutex();
297 299
298 // Register built-in status plug-ins. RegisterPlugin is not used because 300 // Register built-in status plug-ins. RegisterPlugin is not used because
299 // this isn't called within an isolate, and because parameter checking 301 // this isn't called within an isolate, and because parameter checking
300 // isn't necessary. 302 // isn't necessary.
301 instance_->RegisterPlugin(&Dart_GetVmStatus); 303 instance_->RegisterPlugin(&Dart_GetVmStatus);
302 304
303 // TODO(tball): dynamically load any additional plug-ins. 305 // TODO(tball): dynamically load any additional plug-ins.
304 } 306 }
305 307
306 308
307 int VmStatusService::RegisterPlugin(Dart_VmStatusCallback callback) { 309 int VmStatusService::RegisterPlugin(Dart_VmStatusCallback callback) {
308 MutexLocker ml(&mutex_); 310 MutexLocker ml(mutex_);
309 if (callback == NULL) { 311 if (callback == NULL) {
310 return -1; 312 return -1;
311 } 313 }
312 VmStatusPlugin* plugin = new VmStatusPlugin(callback); 314 VmStatusPlugin* plugin = new VmStatusPlugin(callback);
313 VmStatusPlugin* list = instance_->registered_plugin_list_; 315 VmStatusPlugin* list = instance_->registered_plugin_list_;
314 if (list == NULL) { 316 if (list == NULL) {
315 instance_->registered_plugin_list_ = plugin; 317 instance_->registered_plugin_list_ = plugin;
316 } else { 318 } else {
317 list->Append(plugin); 319 list->Append(plugin);
318 } 320 }
319 return 0; 321 return 0;
320 } 322 }
321 323
322 324
323 char* VmStatusService::GetVmStatus(const char* request) { 325 char* VmStatusService::GetVmStatus(const char* request) {
324 VmStatusPlugin* plugin = instance_->registered_plugin_list_; 326 VmStatusPlugin* plugin = instance_->registered_plugin_list_;
325 while (plugin != NULL) { 327 while (plugin != NULL) {
326 char* result = (plugin->callback())(request); 328 char* result = (plugin->callback())(request);
327 if (result != NULL) { 329 if (result != NULL) {
328 return result; 330 return result;
329 } 331 }
330 plugin = plugin->next(); 332 plugin = plugin->next();
331 } 333 }
332 return NULL; 334 return NULL;
333 } 335 }
OLDNEW
« no previous file with comments | « runtime/bin/vmstats_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698