text: 
  /*
   * Copyright (C) Igor Sysoev
   */
  
  
  #include <ngx_config.h>
  #include <ngx_core.h>
  
  /*
   * declare Profiler here interface because
   * <google/profiler.h> is C++ header file
   */
  
  int ProfilerStart(u_char* fname);
  void ProfilerStop(void);
  void ProfilerRegisterThread(void);
  
  
  static void *ngx_google_perftools_create_conf(ngx_cycle_t *cycle);
  static ngx_int_t ngx_google_perftools_worker(ngx_cycle_t *cycle);
  
  
  typedef struct {
      ngx_str_t  profiles;
  } ngx_google_perftools_conf_t;
  
  
  static ngx_command_t  ngx_google_perftools_commands[] = {
  
      { ngx_string("google_perftools_profiles"),
        NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        ngx_conf_set_str_slot,
        0,
        offsetof(ngx_google_perftools_conf_t, profiles),
        NULL },
  
      ngx_null_command
  };
  
  
  static ngx_core_module_t  ngx_google_perftools_module_ctx = {
      ngx_string("google_perftools"),
      ngx_google_perftools_create_conf,
      NULL
  };
  
  
  ngx_module_t  ngx_google_perftools_module = {
      NGX_MODULE_V1,
      &ngx_google_perftools_module_ctx,      /* module context */
      ngx_google_perftools_commands,         /* module directives */
      NGX_CORE_MODULE,                       /* module type */
      NULL,                                  /* init master */
      NULL,                                  /* init module */
      ngx_google_perftools_worker,           /* init process */
      NULL,                                  /* init thread */
      NULL,                                  /* exit thread */
      NULL,                                  /* exit process */
      NULL,                                  /* exit master */
      NGX_MODULE_V1_PADDING
  };
  
  
  static void *
  ngx_google_perftools_create_conf(ngx_cycle_t *cycle)
  {
      ngx_google_perftools_conf_t  *gptcf;
  
      gptcf = ngx_pcalloc(cycle->pool, sizeof(ngx_google_perftools_conf_t));
      if (gptcf == NULL) {
          return NULL;
      }
  
      /*
       * set by pcalloc()
       *
       *     gptcf->profiles = { 0, NULL };
       */
  
      return gptcf;
  }
  
  
  static ngx_int_t
  ngx_google_perftools_worker(ngx_cycle_t *cycle)
  {
      u_char                       *profile;
      ngx_google_perftools_conf_t  *gptcf;
  
      gptcf = (ngx_google_perftools_conf_t *)
                  ngx_get_conf(cycle->conf_ctx, ngx_google_perftools_module);
  
      if (gptcf->profiles.len == 0) {
          return NGX_OK;
      }
  
      profile = ngx_alloc(gptcf->profiles.len + NGX_INT_T_LEN + 2, cycle->log);
      if (profile == NULL) {
          return NGX_OK;
      }
  
      if (getenv("CPUPROFILE")) {
  
          /* disable inherited Profiler enabled in master process */
          ProfilerStop();
      }
  
      ngx_sprintf(profile, "%V.%d%Z", &gptcf->profiles, ngx_pid);
  
      if (ProfilerStart(profile)) {
  
          /* start ITIMER_PROF timer */
          ProfilerRegisterThread();
  
      } else {
          ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
                        "ProfilerStart(%s) failed", profile);
      }
  
      ngx_free(profile);
  
      return NGX_OK;
  }
  
  
  /* ProfilerStop() is called on Profiler destruction */
  