Ticket #1862: profiler2.patch
File profiler2.patch, 10.5 KB (added by , 11 years ago) |
---|
-
binaries/data/config/default.cfg
41 41 ; Force a non-standard bit depth (if 0 then use the current desktop bit depth) 42 42 bpp = 0 43 43 44 ; HTTP profiler server binding 45 profiler2.listen_port = "127.0.0.1:8000" 46 44 47 ; System settings: 45 48 46 49 waternormals = true … … 313 316 ; > PROFILER 314 317 hotkey.profile.toggle = "F11" ; Enable/disable real-time profiler 315 318 hotkey.profile.save = "Shift+F11" ; Save current profiler data to logs/profile.txt 316 hotkey.profile2.enable = "F11" ; Enable HTTP/GPU modes for new profiler 319 hotkey.profile2.enable = "F11" ; Enable GPU mode for new profiler 320 hotkey.profile2.toggle_http = "Ctrl+F11" ; Enable or disable HTTP mode for new profiler 317 321 318 322 profiler2.http.autoenable = false ; Enable HTTP server output at startup (default off for security/performance) 319 323 profiler2.script.enable = false ; Enable Javascript profiling. Needs to be set before startup and can't be changed later. (default off for performance) -
source/main.cpp
164 164 else if (hotkey == "profile2.enable") 165 165 { 166 166 g_Profiler2.EnableGPU(); 167 g_Profiler2.EnableHTTP();168 167 return IN_HANDLED; 169 168 } 169 else if (hotkey == "profile2.toggle_http") 170 { 171 g_Profiler2.ToggleHTTP(); 172 return IN_HANDLED; 173 } 170 174 break; 171 175 } 172 176 -
source/ps/Profiler2.cpp
23 23 #include "precompiled.h" 24 24 25 25 #include "Profiler2.h" 26 #include "ConfigDB.h" 26 27 27 28 #include "lib/allocators/shared_ptr.h" 28 29 #include "ps/CLogger.h" … … 154 155 m_GPU = new CProfiler2GPU(*this); 155 156 } 156 157 157 voidCProfiler2::EnableHTTP()158 bool CProfiler2::EnableHTTP() 158 159 { 159 160 ENSURE(m_Initialised); 160 161 161 162 // Ignore multiple enablings 162 163 if (m_MgContext) 163 return; 164 { 165 LOGWARNING(L"HTTP profiling server already enabled."); 166 return true; 167 } 164 168 169 const char *listening_ports = NULL; 170 CConfigValue *listening_ports_cfg = g_ConfigDB.GetValue(CFG_DEFAULT, "profiler2.listen_port"); 171 if (listening_ports_cfg) 172 listening_ports = listening_ports_cfg->m_String.c_str(); 173 else 174 listening_ports = "127.0.0.1:8000"; 165 175 const char *options[] = { 166 "listening_ports", "127.0.0.1:8000", // bind to localhost for security176 "listening_ports", listening_ports, 167 177 "num_threads", "6", // enough for the browser's parallel connection limit 168 178 NULL 169 179 }; 170 180 m_MgContext = mg_start(MgCallback, this, options); 171 ENSURE(m_MgContext); 181 if (!m_MgContext) 182 { 183 mg_error error = mg_get_last_error(); 184 LOGERROR(L"Failed to start HTTP profiling server on %hs, mg_error: %hs", listening_ports, mg_get_error_string(error)); 185 } 186 else 187 { 188 LOGWARNING(L"Started HTTP profiling server on %hs", listening_ports); 189 } 190 return IsHTTPEnabled(); 172 191 } 173 192 174 193 void CProfiler2::EnableGPU() … … 183 202 SAFE_DELETE(m_GPU); 184 203 } 185 204 186 void CProfiler2::Shutdown ()205 void CProfiler2::ShutdownHTTP() 187 206 { 188 207 ENSURE(m_Initialised); 189 208 190 ENSURE(!m_GPU); // must shutdown GPU before profiler191 192 209 if (m_MgContext) 193 210 { 211 LOGWARNING(L"Shutting down HTTP profiling server."); 194 212 mg_stop(m_MgContext); 195 213 m_MgContext = NULL; 196 214 } 215 } 197 216 217 void CProfiler2::ToggleHTTP() 218 { 219 ENSURE(m_Initialised); 220 221 if (IsHTTPEnabled()) 222 { 223 ShutdownHTTP(); 224 } 225 else 226 { 227 EnableHTTP(); 228 } 229 } 230 231 void CProfiler2::Shutdown() 232 { 233 ENSURE(m_Initialised); 234 235 ENSURE(!m_GPU); // must shutdown GPU before profiler 236 237 ShutdownHTTP(); 238 198 239 // TODO: free non-NULL keys, instead of leaking them 199 240 200 241 int err = pthread_key_delete(m_TLS); -
source/ps/Profiler2.h
261 261 * (Disabled by default for security and performance 262 262 * and to avoid annoying a firewall.) 263 263 */ 264 voidEnableHTTP();264 bool EnableHTTP(); 265 265 266 266 /** 267 267 * Call in main thread to enable the GPU profiling support, … … 276 276 void ShutdownGPU(); 277 277 278 278 /** 279 * Call in main thread to shut down the HTTP server. 280 */ 281 void ShutdownHTTP(); 282 283 /** 284 * Call in main thread to shut down or start the HTTP server. 285 */ 286 void ToggleHTTP(); 287 288 /** 289 * Call in any thread to get HTTP server status. 290 */ 291 bool IsHTTPEnabled() { return m_MgContext != NULL; } 292 293 /** 279 294 * Call in main thread to shut everything down. 280 295 * All other profiled threads should have been terminated already. 281 296 */ -
source/third_party/mongoose/mongoose.cpp
602 602 return err == 0 ? "" : ERR_error_string(err, NULL); 603 603 } 604 604 605 // last internal error 606 static mg_error last_error = MG_ERROR_NONE; 607 608 // Return last encountered error. Only mg_start produces such errors at the moment. 609 enum mg_error mg_get_last_error() 610 { 611 mg_error error = last_error; 612 last_error = MG_ERROR_NONE; 613 return error; 614 } 615 616 // Returns description of error code. 617 const char *mg_get_error_string(mg_error error_code) 618 { 619 switch (error_code) 620 { 621 case MG_ERROR_NONE: 622 return "MG_ERROR_NONE"; 623 case MG_START_INVALID_OPTION: 624 return "MG_START_INVALID_OPTION (some invalid option was provided)"; 625 case MG_START_OPTION_IS_NULL: 626 return "MG_START_OPTION_IS_NULL (option value was NULL)"; 627 case MG_START_GLOBAL_PASSWORDS_OPTION_ERROR: 628 return "MG_START_GLOBAL_PASSWORDS_OPTION_ERROR (failed to load global passwords file or directory)"; 629 case MG_START_LISTENING_PORTS_INVALID: 630 return "MG_START_LISTENING_PORTS_INVALID (invalid format of listening_ports option)"; 631 case MG_START_LISTENING_PORTS_SSL_ERROR: 632 return "MG_START_LISTENING_PORTS_SSL_ERROR (error when trying to start listening to SSL port)"; 633 case MG_START_LISTENING_PORTS_CANNOT_BIND: 634 return "MG_START_LISTENING_PORTS_CANNOT_BIND (failed to bind to one of specified ports)"; 635 case MG_START_LISTENING_PORTS_LISTENER_ALLOC_ERROR: 636 return "MG_START_LISTENING_PORTS_LISTENER_ALLOC_ERROR (not enough memory to initialize listener)"; 637 default: 638 static char buf[4]; 639 sprintf(buf, "%d", error_code); 640 return buf; 641 } 642 } 643 605 644 // Return fake connection structure. Used for logging, if connection 606 645 // is not applicable at the moment of logging. 607 646 static struct mg_connection *fc(struct mg_context *ctx) { … … 3472 3511 if (!parse_port_string(&vec, &so)) { 3473 3512 cry(fc(ctx), "%s: %.*s: invalid port spec. Expecting list of: %s", 3474 3513 __func__, (int) vec.len, vec.ptr, "[IP_ADDRESS:]PORT[s|p]"); 3514 last_error = MG_START_LISTENING_PORTS_INVALID; 3475 3515 success = 0; 3476 3516 } else if (so.is_ssl && ctx->ssl_ctx == NULL) { 3477 3517 cry(fc(ctx), "Cannot add SSL socket, is -ssl_certificate option set?"); 3518 last_error = MG_START_LISTENING_PORTS_SSL_ERROR; 3478 3519 success = 0; 3479 3520 } else if ((sock = socket(PF_INET, SOCK_STREAM, 6)) == INVALID_SOCKET || 3480 3521 #if !defined(_WIN32) … … 3497 3538 closesocket(sock); 3498 3539 cry(fc(ctx), "%s: cannot bind to %.*s: %s", __func__, 3499 3540 (int) vec.len, vec.ptr, strerror(ERRNO)); 3541 last_error = MG_START_LISTENING_PORTS_CANNOT_BIND; 3500 3542 success = 0; 3501 3543 } else if ((listener = (struct socket *) 3502 3544 calloc(1, sizeof(*listener))) == NULL) { 3503 3545 closesocket(sock); 3504 3546 cry(fc(ctx), "%s: %s", __func__, strerror(ERRNO)); 3547 last_error = MG_START_LISTENING_PORTS_LISTENER_ALLOC_ERROR; 3505 3548 success = 0; 3506 3549 } else { 3507 3550 *listener = so; … … 3786 3829 static int set_gpass_option(struct mg_context *ctx) { 3787 3830 struct mgstat mgstat; 3788 3831 const char *path = ctx->config[GLOBAL_PASSWORDS_FILE]; 3789 return path == NULL || mg_stat(path, &mgstat) == 0; 3832 bool success = path == NULL || mg_stat(path, &mgstat) == 0; 3833 if (!success) 3834 last_error = MG_START_GLOBAL_PASSWORDS_OPTION_ERROR; 3835 return success; 3790 3836 } 3791 3837 3792 3838 static int set_acl_option(struct mg_context *ctx) { … … 4237 4283 if ((i = get_option_index(name)) == -1) { 4238 4284 cry(fc(ctx), "Invalid option: %s", name); 4239 4285 free_context(ctx); 4286 last_error = MG_START_INVALID_OPTION; 4240 4287 return NULL; 4241 4288 } else if ((value = *options++) == NULL) { 4242 4289 cry(fc(ctx), "%s: option value cannot be NULL", name); 4243 4290 free_context(ctx); 4291 last_error = MG_START_OPTION_IS_NULL; 4244 4292 return NULL; 4245 4293 } 4246 4294 ctx->config[i] = mg_strdup(value); … … 4270 4318 #endif 4271 4319 !set_acl_option(ctx)) { 4272 4320 free_context(ctx); 4321 // do not set last_error here, set_xxx_option functions should take care of it. 4273 4322 return NULL; 4274 4323 } 4275 4324 -
source/third_party/mongoose/mongoose.h
60 60 // SSL context is passed to the callback function. 61 61 }; 62 62 63 // Various errors that could be reported by Mongoose. Purpose is to extend error reporting. 64 enum mg_error { 65 MG_ERROR_NONE, 66 67 // errors after mg_start 68 MG_START_INVALID_OPTION, // some invalid option was provided 69 MG_START_OPTION_IS_NULL, // option value was NULL 70 MG_START_GLOBAL_PASSWORDS_OPTION_ERROR, // failed to load global passwords file or directory 71 MG_START_LISTENING_PORTS_INVALID, // invalid format of listening_ports option 72 MG_START_LISTENING_PORTS_SSL_ERROR, // error when trying to start listening to SSL port 73 MG_START_LISTENING_PORTS_CANNOT_BIND, // failed to bind to one of specified ports 74 MG_START_LISTENING_PORTS_LISTENER_ALLOC_ERROR, // not enough memory to initialize listener 75 }; 76 77 // Returns description of error code. 78 const char *mg_get_error_string(mg_error error_code); 79 80 // Retrieve detailed error code after some of mg_ functions fail. 81 // 82 // Resets last error code afterwards. 83 // Only mg_start produces such errors at the moment. 84 // 85 // Return: 86 // If there was no error or function that failed doesn't support extended error reporting 87 // MG_ERROR_NONE is returned. Otherwise you get last error code. 88 enum mg_error mg_get_last_error(); 89 63 90 // Prototype for the user-defined function. Mongoose calls this function 64 91 // on every MG_* event. 65 92 //