diff src/misc/ngx_google_perftools_module.c @ 370:9a242235a80a NGINX_0_6_29

nginx 0.6.29 *) Feature: the ngx_google_perftools_module. *) Bugfix: the ngx_http_perl_module could be not built on 64-bit platforms; bug appeared in 0.6.27.
author Igor Sysoev <http://sysoev.ru>
date Tue, 18 Mar 2008 00:00:00 +0300
parents
children be4f34123024
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/misc/ngx_google_perftools_module.c
@@ -0,0 +1,127 @@
+
+/*
+ * 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 */