Ticket #1862: profiler2.patch

File profiler2.patch, 10.5 KB (added by metalhead, 11 years ago)
  • binaries/data/config/default.cfg

     
    4141; Force a non-standard bit depth (if 0 then use the current desktop bit depth)
    4242bpp = 0
    4343
     44; HTTP profiler server binding
     45profiler2.listen_port = "127.0.0.1:8000"
     46
    4447; System settings:
    4548
    4649waternormals = true
     
    313316; > PROFILER
    314317hotkey.profile.toggle = "F11"               ; Enable/disable real-time profiler
    315318hotkey.profile.save = "Shift+F11"           ; Save current profiler data to logs/profile.txt
    316 hotkey.profile2.enable = "F11"              ; Enable HTTP/GPU modes for new profiler
     319hotkey.profile2.enable = "F11"              ; Enable GPU mode for new profiler
     320hotkey.profile2.toggle_http = "Ctrl+F11"    ; Enable or disable HTTP mode for new profiler
    317321
    318322profiler2.http.autoenable = false           ; Enable HTTP server output at startup (default off for security/performance)
    319323profiler2.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

     
    164164        else if (hotkey == "profile2.enable")
    165165        {
    166166            g_Profiler2.EnableGPU();
    167             g_Profiler2.EnableHTTP();
    168167            return IN_HANDLED;
    169168        }
     169        else if (hotkey == "profile2.toggle_http")
     170        {
     171            g_Profiler2.ToggleHTTP();
     172            return IN_HANDLED;
     173        }
    170174        break;
    171175    }
    172176
  • source/ps/Profiler2.cpp

     
    2323#include "precompiled.h"
    2424
    2525#include "Profiler2.h"
     26#include "ConfigDB.h"
    2627
    2728#include "lib/allocators/shared_ptr.h"
    2829#include "ps/CLogger.h"
     
    154155    m_GPU = new CProfiler2GPU(*this);
    155156}
    156157
    157 void CProfiler2::EnableHTTP()
     158bool CProfiler2::EnableHTTP()
    158159{
    159160    ENSURE(m_Initialised);
    160161
    161162    // Ignore multiple enablings
    162163    if (m_MgContext)
    163         return;
     164    {
     165        LOGWARNING(L"HTTP profiling server already enabled.");
     166        return true;
     167    }
    164168
     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";
    165175    const char *options[] = {
    166         "listening_ports", "127.0.0.1:8000", // bind to localhost for security
     176        "listening_ports", listening_ports,
    167177        "num_threads", "6", // enough for the browser's parallel connection limit
    168178        NULL
    169179    };
    170180    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();
    172191}
    173192
    174193void CProfiler2::EnableGPU()
     
    183202    SAFE_DELETE(m_GPU);
    184203}
    185204
    186 void CProfiler2::Shutdown()
     205void CProfiler2::ShutdownHTTP()
    187206{
    188207    ENSURE(m_Initialised);
    189208
    190     ENSURE(!m_GPU); // must shutdown GPU before profiler
    191 
    192209    if (m_MgContext)
    193210    {
     211        LOGWARNING(L"Shutting down HTTP profiling server.");
    194212        mg_stop(m_MgContext);
    195213        m_MgContext = NULL;
    196214    }
     215}
    197216
     217void CProfiler2::ToggleHTTP()
     218{
     219    ENSURE(m_Initialised);
     220
     221    if (IsHTTPEnabled())
     222    {
     223        ShutdownHTTP();
     224    }
     225    else
     226    {
     227        EnableHTTP();
     228    }
     229}
     230
     231void CProfiler2::Shutdown()
     232{
     233    ENSURE(m_Initialised);
     234
     235    ENSURE(!m_GPU); // must shutdown GPU before profiler
     236
     237    ShutdownHTTP();
     238
    198239    // TODO: free non-NULL keys, instead of leaking them
    199240
    200241    int err = pthread_key_delete(m_TLS);
  • source/ps/Profiler2.h

     
    261261     * (Disabled by default for security and performance
    262262     * and to avoid annoying a firewall.)
    263263     */
    264     void EnableHTTP();
     264    bool EnableHTTP();
    265265
    266266    /**
    267267     * Call in main thread to enable the GPU profiling support,
     
    276276    void ShutdownGPU();
    277277
    278278    /**
     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    /**
    279294     * Call in main thread to shut everything down.
    280295     * All other profiled threads should have been terminated already.
    281296     */
  • source/third_party/mongoose/mongoose.cpp

     
    602602  return err == 0 ? "" : ERR_error_string(err, NULL);
    603603}
    604604
     605// last internal error
     606static mg_error last_error = MG_ERROR_NONE;
     607
     608// Return last encountered error. Only mg_start produces such errors at the moment.
     609enum 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.
     617const 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
    605644// Return fake connection structure. Used for logging, if connection
    606645// is not applicable at the moment of logging.
    607646static struct mg_connection *fc(struct mg_context *ctx) {
     
    34723511    if (!parse_port_string(&vec, &so)) {
    34733512      cry(fc(ctx), "%s: %.*s: invalid port spec. Expecting list of: %s",
    34743513          __func__, (int) vec.len, vec.ptr, "[IP_ADDRESS:]PORT[s|p]");
     3514      last_error = MG_START_LISTENING_PORTS_INVALID;
    34753515      success = 0;
    34763516    } else if (so.is_ssl && ctx->ssl_ctx == NULL) {
    34773517      cry(fc(ctx), "Cannot add SSL socket, is -ssl_certificate option set?");
     3518      last_error = MG_START_LISTENING_PORTS_SSL_ERROR;
    34783519      success = 0;
    34793520    } else if ((sock = socket(PF_INET, SOCK_STREAM, 6)) == INVALID_SOCKET ||
    34803521#if !defined(_WIN32)
     
    34973538      closesocket(sock);
    34983539      cry(fc(ctx), "%s: cannot bind to %.*s: %s", __func__,
    34993540          (int) vec.len, vec.ptr, strerror(ERRNO));
     3541      last_error = MG_START_LISTENING_PORTS_CANNOT_BIND;
    35003542      success = 0;
    35013543    } else if ((listener = (struct socket *)
    35023544                calloc(1, sizeof(*listener))) == NULL) {
    35033545      closesocket(sock);
    35043546      cry(fc(ctx), "%s: %s", __func__, strerror(ERRNO));
     3547      last_error = MG_START_LISTENING_PORTS_LISTENER_ALLOC_ERROR;
    35053548      success = 0;
    35063549    } else {
    35073550      *listener = so;
     
    37863829static int set_gpass_option(struct mg_context *ctx) {
    37873830  struct mgstat mgstat;
    37883831  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;
    37903836}
    37913837
    37923838static int set_acl_option(struct mg_context *ctx) {
     
    42374283    if ((i = get_option_index(name)) == -1) {
    42384284      cry(fc(ctx), "Invalid option: %s", name);
    42394285      free_context(ctx);
     4286      last_error = MG_START_INVALID_OPTION;
    42404287      return NULL;
    42414288    } else if ((value = *options++) == NULL) {
    42424289      cry(fc(ctx), "%s: option value cannot be NULL", name);
    42434290      free_context(ctx);
     4291      last_error = MG_START_OPTION_IS_NULL;
    42444292      return NULL;
    42454293    }
    42464294    ctx->config[i] = mg_strdup(value);
     
    42704318#endif
    42714319      !set_acl_option(ctx)) {
    42724320    free_context(ctx);
     4321    // do not set last_error here, set_xxx_option functions should take care of it.
    42734322    return NULL;
    42744323  }
    42754324
  • source/third_party/mongoose/mongoose.h

     
    6060                    // SSL context is passed to the callback function.
    6161};
    6262
     63// Various errors that could be reported by Mongoose. Purpose is to extend error reporting.
     64enum 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.
     78const 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.
     88enum mg_error mg_get_last_error();
     89
    6390// Prototype for the user-defined function. Mongoose calls this function
    6491// on every MG_* event.
    6592//