summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2014-03-16 13:49:06 -0300
committershennetsind <ind@henn.et>2014-03-16 13:49:06 -0300
commit2656f7f4026708f210c6ce7c39f5fc6831597982 (patch)
tree1dd5ee1a8152982b32ae8db4a6a2b01310f2d9c0
parent8c6547a5c3ec4d6b1845b60d14b0aae5c827892c (diff)
downloadhercules-2656f7f4026708f210c6ce7c39f5fc6831597982.tar.gz
hercules-2656f7f4026708f210c6ce7c39f5fc6831597982.tar.bz2
hercules-2656f7f4026708f210c6ce7c39f5fc6831597982.tar.xz
hercules-2656f7f4026708f210c6ce7c39f5fc6831597982.zip
Improved ERS memory handling
On shutdown the ERS will loop thru leftover managers and clear them according to each manager's settings, while also printing errors according to each manager's settings. Will also help pinpoint the causes of http://hercules.ws/board/tracker/issue-8093-memory-leak-after-stop-server-cant-fix/ and similar issues. Signed-off-by: shennetsind <ind@henn.et>
-rw-r--r--src/common/core.c2
-rw-r--r--src/common/ers.c28
-rw-r--r--src/common/ers.h15
3 files changed, 21 insertions, 24 deletions
diff --git a/src/common/core.c b/src/common/core.c
index 86634ec4b..c6075da40 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -20,6 +20,7 @@
#include "../common/HPM.h"
#include "../common/utils.h"
#include "../common/conf.h"
+ #include "../common/ers.h"
#endif
#include <stdio.h>
@@ -372,6 +373,7 @@ int main (int argc, char **argv) {
sockt->final();
DB->final();
rathread_final();
+ ers_final();
#endif
iMalloc->final();
diff --git a/src/common/ers.c b/src/common/ers.c
index eb351a988..5a3d7314a 100644
--- a/src/common/ers.c
+++ b/src/common/ers.c
@@ -115,17 +115,14 @@ struct ers_instance_t {
#ifdef DEBUG
/* for data analysis [Ind/Hercules] */
unsigned int Peak;
- struct ers_instance_t *Next, *Prev;
#endif
-
+ struct ers_instance_t *Next, *Prev;
};
// Array containing a pointer for all ers_cache structures
static ers_cache_t *CacheList = NULL;
-#ifdef DEBUG
- static struct ers_instance_t *InstanceList = NULL;
-#endif
+static struct ers_instance_t *InstanceList = NULL;
/**
* @param Options the options from the instance seeking a cache, we use it to give it a cache with matching configuration
@@ -180,6 +177,7 @@ static void ers_free_cache(ers_cache_t *cache, bool remove)
CacheList = cache->Next;
aFree(cache->Blocks);
+
aFree(cache);
}
@@ -285,7 +283,6 @@ static void ers_obj_destroy(ERS self)
if (--instance->Cache->ReferenceCount <= 0)
ers_free_cache(instance->Cache, true);
-#ifdef DEBUG
if (instance->Next)
instance->Next->Prev = instance->Prev;
@@ -293,7 +290,6 @@ static void ers_obj_destroy(ERS self)
instance->Prev->Next = instance->Next;
else
InstanceList = instance->Next;
-#endif
if( instance->Options & ERS_OPT_FREE_NAME )
aFree(instance->Name);
@@ -335,7 +331,7 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options)
instance->Cache = ers_find_cache(size,instance->Options);
instance->Cache->ReferenceCount++;
-#ifdef DEBUG
+
if (InstanceList == NULL) {
InstanceList = instance;
} else {
@@ -344,7 +340,6 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options)
InstanceList = instance;
InstanceList->Prev = NULL;
}
-#endif
instance->Count = 0;
@@ -392,12 +387,17 @@ void ers_report(void) {
ShowInfo("ers_report: '"CL_WHITE"%u"CL_NORMAL"' blocks total, consuming '"CL_WHITE"%.2f MB"CL_NORMAL"' \n",blocks_a,(double)((memory_t)/1024)/1024);
}
-void ers_force_destroy_all(void)
-{
- ers_cache_t *cache;
+/**
+ * Call on shutdown to clear remaining entries
+ **/
+void ers_final(void) {
+ struct ers_instance_t *instance = InstanceList, *next;
- for (cache = CacheList; cache; cache = cache->Next)
- ers_free_cache(cache, false);
+ while( instance ) {
+ next = instance->Next;
+ ers_obj_destroy((ERS)instance);
+ instance = next;
+ }
}
#endif
diff --git a/src/common/ers.h b/src/common/ers.h
index 4dae19f3b..23a996923 100644
--- a/src/common/ers.h
+++ b/src/common/ers.h
@@ -49,7 +49,7 @@
* ERS - Entry manager. *
* ers_new - Allocate an instance of an entry manager. *
* ers_report - Print a report about the current state. *
- * ers_force_destroy_all - Force the destruction of all the managers. *
+ * ers_final - Clears the remainder of the manangers. *
\*****************************************************************************/
/**
@@ -138,7 +138,7 @@ typedef struct eri {
// Disable the public functions
# define ers_new(size,name,options) NULL
# define ers_report()
-# define ers_force_destroy_all()
+# define ers_final()
#else /* not DISABLE_ERS */
// These defines should be used to allow the code to keep working whenever
// the system is disabled
@@ -170,14 +170,9 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options);
void ers_report(void);
/**
- * Forcibly destroy all the entry managers, checking for nothing.
- * The system is left as if no instances or entries had ever been allocated.
- * All previous entries and instances of the managers become invalid.
- * The use of this is NOT recommended.
- * It should only be used in extreme situations to make shure all the memory
- * allocated by this system is released.
- */
-void ers_force_destroy_all(void);
+ * Clears the remainder of the manangers
+ **/
+void ers_final(void);
#endif /* DISABLE_ERS / not DISABLE_ERS */
#endif /* _COMMON_ERS_H_ */