Parcourir la source

Prepare data for server status (#243)

bel2125 il y a 8 ans
Parent
commit
a8af15db2c
2 fichiers modifiés avec 143 ajouts et 19 suppressions
  1. 1 1
      include/civetweb.h
  2. 142 18
      src/civetweb.c

+ 1 - 1
include/civetweb.h

@@ -1019,7 +1019,7 @@ CIVETWEB_API char *mg_md5(char buf[33], ...);
 
 /* Print error message to the opened error log stream.
    This utilizes the provided logging configuration.
-     conn: connection
+     conn: connection (not used for sending data, but to get perameters)
      fmt: format string without the line return
      ...: variable argument list
    Example:

+ 142 - 18
src/civetweb.c

@@ -846,25 +846,87 @@ mg_atomic_dec(volatile int *addr)
 }
 
 
-#if defined(MEMORY_DEBUGGING)
-static unsigned long mg_memory_debug_blockCount = 0;
-static unsigned long mg_memory_debug_totalMemUsed = 0;
+#if defined(__GNUC__) || defined(__MINGW32__)
+/* Show no warning in case system functions are not used. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+#if defined(__clang__)
+/* Show no warning in case system functions are not used. */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+
+static int
+mg_atomic_add(volatile int *addr, int value)
+{
+	int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+	/* Depending on the SDK, this function uses either
+	 * (volatile unsigned int *) or (volatile LONG *),
+	 * so whatever you use, the other SDK is likely to raise a warning. */
+	ret = InterlockedAdd((volatile long *)addr, (long)value);
+#elif defined(__GNUC__)                                                        \
+    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))
+	ret = __sync_add_and_fetch(addr, value);
+#else
+	ret = (++(*addr));
+#endif
+	return ret;
+}
+
+
+#if defined(__GNUC__)
+/* Show no warning in case system functions are not used. */
+#pragma GCC diagnostic pop
+#endif
+#if defined(__clang__)
+/* Show no warning in case system functions are not used. */
+#pragma clang diagnostic pop
+#endif
+
+
+#if defined(USE_SERVER_STATS)
+
+// static unsigned long mg_memory_debug_blockCount = 0;
+// static unsigned long mg_memory_debug_totalMemUsed = 0;
+
+volatile int mg_memory_debug_blockCount = 0;
+volatile int mg_memory_debug_totalMemUsed = 0;
+volatile int mg_memory_debug_maxMemUsed = 0;
 
 
 static void *
-mg_malloc_ex(size_t size, const char *file, unsigned line)
+mg_malloc_ex(size_t size,
+             struct mg_context *ctx,
+             const char *file,
+             unsigned line)
 {
 	void *data = malloc(size + sizeof(size_t));
 	void *memory = 0;
+
+#if defined(MEMORY_DEBUGGING)
 	char mallocStr[256];
+#endif
+
+	(void)ctx;
 
 	if (data) {
+		int mmem = mg_atomic_add(&mg_memory_debug_totalMemUsed, size);
+		if (mmem > mg_memory_debug_maxMemUsed) {
+			/* could use atomic compare exchange, but this
+			 * seems overkill for statistics data */
+			mg_memory_debug_maxMemUsed = mmem;
+		}
+
+
+		mg_atomic_inc(&mg_memory_debug_blockCount);
 		*(size_t *)data = size;
-		mg_memory_debug_totalMemUsed += size;
-		mg_memory_debug_blockCount++;
 		memory = (void *)(((char *)data) + sizeof(size_t));
 	}
 
+#if defined(MEMORY_DEBUGGING)
 	sprintf(mallocStr,
 	        "MEM: %p %5lu alloc   %7lu %4lu --- %s:%u\n",
 	        memory,
@@ -878,15 +940,23 @@ mg_malloc_ex(size_t size, const char *file, unsigned line)
 #else
 	DEBUG_TRACE("%s", mallocStr);
 #endif
+#endif
 
 	return memory;
 }
 
 
 static void *
-mg_calloc_ex(size_t count, size_t size, const char *file, unsigned line)
+mg_calloc_ex(size_t count,
+             size_t size,
+             struct mg_context *ctx,
+             const char *file,
+             unsigned line)
 {
 	void *data = mg_malloc_ex(size * count, file, line);
+
+	(void)ctx;
+
 	if (data) {
 		memset(data, 0, size * count);
 	}
@@ -895,16 +965,24 @@ mg_calloc_ex(size_t count, size_t size, const char *file, unsigned line)
 
 
 static void
-mg_free_ex(void *memory, const char *file, unsigned line)
+mg_free_ex(void *memory,
+           struct mg_context *ctx,
+           const char *file,
+           unsigned line)
 {
+#if defined(MEMORY_DEBUGGING)
 	char mallocStr[256];
+#endif
 	void *data = (void *)(((char *)memory) - sizeof(size_t));
 	size_t size;
 
+	(void)ctx;
+
 	if (memory) {
 		size = *(size_t *)data;
-		mg_memory_debug_totalMemUsed -= size;
-		mg_memory_debug_blockCount--;
+		mg_atomic_add(&mg_memory_debug_totalMemUsed, -size);
+		mg_atomic_dec(&mg_memory_debug_blockCount);
+#if defined(MEMORY_DEBUGGING)
 		sprintf(mallocStr,
 		        "MEM: %p %5lu free    %7lu %4lu --- %s:%u\n",
 		        memory,
@@ -918,20 +996,28 @@ mg_free_ex(void *memory, const char *file, unsigned line)
 #else
 		DEBUG_TRACE("%s", mallocStr);
 #endif
-
+#endif
 		free(data);
 	}
 }
 
 
 static void *
-mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line)
+mg_realloc_ex(void *memory,
+              size_t newsize,
+              struct mg_context *ctx,
+              const char *file,
+              unsigned line)
 {
+#if defined(MEMORY_DEBUGGING)
 	char mallocStr[256];
+#endif
 	void *data;
 	void *_realloc;
 	size_t oldsize;
 
+	(void)ctx;
+
 	if (newsize) {
 		if (memory) {
 			data = (void *)(((char *)memory) - sizeof(size_t));
@@ -940,6 +1026,7 @@ mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line)
 			if (_realloc) {
 				data = _realloc;
 				mg_memory_debug_totalMemUsed -= oldsize;
+#if defined(MEMORY_DEBUGGING)
 				sprintf(mallocStr,
 				        "MEM: %p %5lu r-free  %7lu %4lu --- %s:%u\n",
 				        memory,
@@ -953,7 +1040,9 @@ mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line)
 #else
 				DEBUG_TRACE("%s", mallocStr);
 #endif
+#endif
 				mg_memory_debug_totalMemUsed += newsize;
+#if defined(MEMORY_DEBUGGING)
 				sprintf(mallocStr,
 				        "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n",
 				        memory,
@@ -967,14 +1056,17 @@ mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line)
 #else
 				DEBUG_TRACE("%s", mallocStr);
 #endif
+#endif
 				*(size_t *)data = newsize;
 				data = (void *)(((char *)data) + sizeof(size_t));
 			} else {
+#if defined(MEMORY_DEBUGGING)
 #if defined(_WIN32)
 				OutputDebugStringA("MEM: realloc failed\n");
 #else
 				DEBUG_TRACE("%s", "MEM: realloc failed\n");
 #endif
+#endif
 				return _realloc;
 			}
 		} else {
@@ -988,12 +1080,17 @@ mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line)
 	return data;
 }
 
-#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__)
-#define mg_calloc(a, b) mg_calloc_ex(a, b, __FILE__, __LINE__)
-#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__)
-#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
+#define mg_malloc(a) mg_malloc_ex(a, NULL, __FILE__, __LINE__)
+#define mg_calloc(a, b) mg_calloc_ex(a, b, NULL, __FILE__, __LINE__)
+#define mg_realloc(a, b) mg_realloc_ex(a, b, NULL, __FILE__, __LINE__)
+#define mg_free(a) mg_free_ex(a, NULL, __FILE__, __LINE__)
 
-#else
+#define mg_malloc_ctx(a, c) mg_malloc_ex(a, c, __FILE__, __LINE__)
+#define mg_calloc_ctx(a, b, c) mg_calloc_ex(a, b, c, __FILE__, __LINE__)
+#define mg_realloc_ctx(a, b, c) mg_realloc_ex(a, b, c, __FILE__, __LINE__)
+#define mg_free_ctx(a, c) mg_free_ex(a, c, __FILE__, __LINE__)
+
+#else /* USE_SERVER_STATS */
 
 static __inline void *
 mg_malloc(size_t a)
@@ -1019,7 +1116,12 @@ mg_free(void *a)
 	free(a);
 }
 
-#endif
+#define mg_malloc_ctx(a, c) mg_malloc(a)
+#define mg_calloc_ctx(a, b, c) mg_calloc(a, b)
+#define mg_realloc_ctx(a, b, c) mg_realloc(a, b)
+#define mg_free_ctx(a, c) mg_free(a)
+
+#endif /* USE_SERVER_STATS */
 
 
 static void mg_vsnprintf(const struct mg_connection *conn,
@@ -1979,6 +2081,13 @@ struct mg_context {
 #if defined(USE_LUA)
 	void *lua_background_state;
 #endif
+
+#if defined(USE_SERVER_STATS)
+	int active_connections;
+	int total_connections;
+	int total_requests;
+	int max_connections;
+#endif
 };
 
 
@@ -14173,6 +14282,16 @@ process_new_connection(struct mg_connection *conn)
 		const char *hostend;
 		int reqerr, uri_type;
 
+#if defined(USE_SERVER_STATS)
+		int mcon = mg_atomic_inc(&(conn->ctx->total_connections));
+		mg_atomic_inc(&(conn->ctx->active_connections));
+		if (mcon > (conn->ctx->max_connections)) {
+			/* could use atomic compare exchange, but this
+			 * seems overkill for statistics data */
+			conn->ctx->max_connections = mcon;
+		}
+#endif
+
 		keep_alive_enabled =
 		    !strcmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
 
@@ -14318,6 +14437,11 @@ process_new_connection(struct mg_connection *conn)
 			conn->handled_requests++;
 
 		} while (keep_alive);
+
+#if defined(USE_SERVER_STATS)
+		mg_atomic_add(&(conn->ctx->total_requests), conn->handled_requests);
+		mg_atomic_dec(&(conn->ctx->active_connections));
+#endif
 	}
 }