summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/db.c2
-rw-r--r--src/common/ers.c37
-rw-r--r--src/common/ers.h9
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/chrif.c2
-rw-r--r--src/map/clif.c42
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/map.c1
-rw-r--r--src/map/mob.c4
-rw-r--r--src/map/npc.c2
-rw-r--r--src/map/pet.c4
-rw-r--r--src/map/skill.c4
-rw-r--r--src/map/status.c2
14 files changed, 67 insertions, 47 deletions
diff --git a/src/common/db.c b/src/common/db.c
index 54834af81..a748cba5a 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -2440,7 +2440,7 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi
db->free_max = 0;
db->free_lock = 0;
/* Other */
- db->nodes = ers_new(sizeof(struct dbn));
+ db->nodes = ers_new(sizeof(struct dbn),"db.c::db_alloc",ERS_OPT_NONE);
db->cmp = db_default_cmp(type);
db->hash = db_default_hash(type);
db->release = db_default_release(type, options);
diff --git a/src/common/ers.c b/src/common/ers.c
index db7cb149d..f7cb7f005 100644
--- a/src/common/ers.c
+++ b/src/common/ers.c
@@ -139,6 +139,16 @@ typedef struct ers_impl {
*/
size_t size;
+ /**
+ * Reference to this instance of the table
+ */
+ char *name;
+
+ /**
+ * Options used by this instance
+ */
+ enum ERSOptions options;
+
} *ERS_impl;
/**
@@ -195,8 +205,8 @@ static void *ers_obj_alloc_entry(ERS self)
} else { // allocate a new block
if (obj->num == obj->max) { // expand the block array
if (obj->max == UINT32_MAX) { // No more space for blocks
- ShowFatalError("ers::alloc : maximum number of blocks reached, increase ERS_BLOCK_ENTRIES.\n"
- "exiting the program...\n");
+ ShowFatalError("ers::alloc : maximum number of blocks reached, increase ERS_BLOCK_ENTRIES. (by %s)\n"
+ "exiting the program...\n",obj->name);
exit(EXIT_FAILURE);
}
obj->max = (obj->max*4)+3; // left shift bits '11' - overflow won't happen
@@ -229,7 +239,7 @@ static void ers_obj_free_entry(ERS self, void *entry)
ShowError("ers::free : NULL object, aborting entry freeing.\n");
return;
} else if (entry == NULL) {
- ShowError("ers::free : NULL entry, nothing to free.\n");
+ ShowError("ers::free : NULL entry in obj '%s', nothing to free.\n",obj->name);
return;
}
@@ -311,15 +321,16 @@ static void ers_obj_destroy(ERS self)
}
}
if (count) { // missing entries
- ShowWarning("ers::destroy : %u entries missing (possible double free), continuing destruction (entry size=%u).\n",
- count, obj->size);
+ if( !(obj->options&ERS_OPT_CLEAR) )
+ ShowWarning("ers::destroy : %u entries missing in '%s' (possible double free), continuing destruction (entry size=%u).\n",
+ count, obj->name, obj->size);
} else if (reuse) { // extra entries
while (reuse && count != UINT32_MAX) {
count++;
reuse = reuse->next;
}
- ShowWarning("ers::destroy : %u extra entries found, continuing destruction (entry size=%u).\n",
- count, obj->size);
+ ShowWarning("ers::destroy : %u extra entries found in '%s', continuing destruction (entry size=%u).\n",
+ count, obj->name, obj->size);
}
// destroy the entry manager
if (obj->max) {
@@ -350,8 +361,7 @@ static void ers_obj_destroy(ERS self)
* @see #ers_root
* @see #ers_num
*/
-ERS ers_new(uint32 size)
-{
+ERS ers_new(uint32 size, char *name, enum ERSOptions options) {
ERS_impl obj;
uint32 i;
@@ -376,8 +386,8 @@ ERS ers_new(uint32 size)
}
// create a new manager to handle the entry size
if (ers_num == ERS_ROOT_SIZE) {
- ShowFatalError("ers_alloc: too many root objects, increase ERS_ROOT_SIZE.\n"
- "exiting the program...\n");
+ ShowFatalError("ers_alloc: too many root objects, increase ERS_ROOT_SIZE. (by %s)\n"
+ "exiting the program...\n",name);
exit(EXIT_FAILURE);
}
obj = (ERS_impl)aMalloc(sizeof(struct ers_impl));
@@ -395,6 +405,9 @@ ERS ers_new(uint32 size)
obj->destroy = 1;
// Properties
obj->size = size;
+ obj->options = options;
+ // Info
+ obj->name = name;
ers_root[ers_num++] = obj;
return &obj->vtable;
}
@@ -460,7 +473,7 @@ void ers_report(void)
reuse = reuse->next;
}
// Entry manager report
- ShowMessage(CL_BOLD"[Entry manager #%u report]\n"CL_NORMAL, i);
+ ShowMessage(CL_BOLD"[Entry manager '%s' #%u report]\n"CL_NORMAL, obj->name, i);
ShowMessage("\tinstances : %u\n", obj->destroy);
ShowMessage("\tentry size : %u\n", obj->size);
ShowMessage("\tblock array size : %u\n", obj->max);
diff --git a/src/common/ers.h b/src/common/ers.h
index 9e120c313..249d325fd 100644
--- a/src/common/ers.h
+++ b/src/common/ers.h
@@ -70,6 +70,11 @@
# define ERS_ALIGNED 1
#endif /* not ERS_ALIGN_ENTRY */
+enum ERSOptions {
+ ERS_OPT_NONE = 0,
+ ERS_OPT_CLEAR = 1,/* silently clears any entries left in the manager upon destruction */
+};
+
/**
* Public interface of the entry manager.
* @param alloc Allocate an entry from this manager
@@ -121,7 +126,7 @@ typedef struct eri {
# define ers_entry_size(obj) (size_t)0
# define ers_destroy(obj)
// Disable the public functions
-# define ers_new(size) NULL
+# define ers_new(size,name) NULL
# define ers_report()
# define ers_force_destroy_all()
#else /* not DISABLE_ERS */
@@ -142,7 +147,7 @@ typedef struct eri {
* @param The requested size of the entry in bytes
* @return Interface of the object
*/
-ERS ers_new(uint32 size);
+ERS ers_new(uint32 size, char *name, enum ERSOptions options);
/**
* Print a report about the current state of the Entry Reusage System.
diff --git a/src/map/battle.c b/src/map/battle.c
index 47cb4a88c..564c08a1f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -5834,7 +5834,7 @@ int battle_config_read(const char* cfgName)
void do_init_battle(void)
{
- delay_damage_ers = ers_new(sizeof(struct delay_damage));
+ delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR);
add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub");
}
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 23b7b372f..064104018 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1598,7 +1598,7 @@ int do_final_chrif(void)
int do_init_chrif(void)
{
auth_db = idb_alloc(DB_OPT_BASE);
- auth_db_ers = ers_new(sizeof(struct auth_node));
+ auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE);
add_timer_func_list(check_connect_char_server, "check_connect_char_server");
add_timer_func_list(ping_char_server, "ping_char_server");
diff --git a/src/map/clif.c b/src/map/clif.c
index 6b03142c3..d368f2955 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -11,6 +11,7 @@
#include "../common/showmsg.h"
#include "../common/strlib.h"
#include "../common/utils.h"
+#include "../common/ers.h"
#include "map.h"
#include "chrif.h"
@@ -48,6 +49,9 @@
#include <stdarg.h>
#include <time.h>
+/* for clif_clearunit_delayed */
+static struct eri *delay_clearunit_ers;
+
//#define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET
@@ -103,18 +107,15 @@ static inline void RBUFPOS(const uint8* p, unsigned short pos, short* x, short*
{
p += pos;
- if( x )
- {
+ if( x ) {
x[0] = ( ( p[0] & 0xff ) << 2 ) | ( p[1] >> 6 );
}
- if( y )
- {
+ if( y ) {
y[0] = ( ( p[1] & 0x3f ) << 4 ) | ( p[2] >> 4 );
}
- if( dir )
- {
+ if( dir ) {
dir[0] = ( p[2] & 0x0f );
}
}
@@ -124,33 +125,27 @@ static inline void RBUFPOS2(const uint8* p, unsigned short pos, short* x0, short
{
p += pos;
- if( x0 )
- {
+ if( x0 ) {
x0[0] = ( ( p[0] & 0xff ) << 2 ) | ( p[1] >> 6 );
}
- if( y0 )
- {
+ if( y0 ) {
y0[0] = ( ( p[1] & 0x3f ) << 4 ) | ( p[2] >> 4 );
}
- if( x1 )
- {
+ if( x1 ) {
x1[0] = ( ( p[2] & 0x0f ) << 6 ) | ( p[3] >> 2 );
}
- if( y1 )
- {
+ if( y1 ) {
y1[0] = ( ( p[3] & 0x03 ) << 8 ) | ( p[4] >> 0 );
}
- if( sx0 )
- {
+ if( sx0 ) {
sx0[0] = ( p[5] & 0xf0 ) >> 4;
}
- if( sy0 )
- {
+ if( sy0 ) {
sy0[0] = ( p[5] & 0x0f ) >> 0;
}
}
@@ -848,13 +843,12 @@ static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr
{
struct block_list *bl = (struct block_list *)data;
clif_clearunit_area(bl, (clr_type) id);
- aFree(bl);
+ ers_free(delay_clearunit_ers,bl);
return 0;
}
void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick)
{
- struct block_list *tbl;
- tbl = (struct block_list*)aMalloc(sizeof (struct block_list));
+ struct block_list *tbl = ers_alloc(delay_clearunit_ers, struct block_list);
memcpy (tbl, bl, sizeof (struct block_list));
add_timer(tick, clif_clearunit_delayed_sub, (int)type, (intptr_t)tbl);
}
@@ -17031,5 +17025,11 @@ int do_init_clif(void) {
add_timer_func_list(clif_clearunit_delayed_sub, "clif_clearunit_delayed_sub");
add_timer_func_list(clif_delayquit, "clif_delayquit");
+ delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
+
return 0;
}
+
+void do_final_clif(void) {
+ ers_destroy(delay_clearunit_ers);
+}
diff --git a/src/map/clif.h b/src/map/clif.h
index d31fb59fe..9039c489c 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -639,6 +639,7 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type);
int do_init_clif(void);
+void do_final_clif(void);
// MAIL SYSTEM
void clif_Mail_window(int fd, int flag);
diff --git a/src/map/guild.c b/src/map/guild.c
index a0e2a3055..23b8bf131 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1990,7 +1990,7 @@ void do_init_guild(void)
castle_db=idb_alloc(DB_OPT_BASE);
guild_expcache_db=idb_alloc(DB_OPT_BASE);
guild_infoevent_db=idb_alloc(DB_OPT_BASE);
- expcache_ers = ers_new(sizeof(struct guild_expcache));
+ expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE);
sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb);
diff --git a/src/map/map.c b/src/map/map.c
index 30198a32c..df2e8765f 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3633,6 +3633,7 @@ void do_final(void)
do_final_atcommand();
do_final_battle();
do_final_chrif();
+ do_final_clif();
do_final_npc();
do_final_script();
do_final_instance();
diff --git a/src/map/mob.c b/src/map/mob.c
index 39bfc6c68..ca4da158b 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -4624,8 +4624,8 @@ int do_init_mob(void)
memset(mob_db_data,0,sizeof(mob_db_data)); //Clear the array
mob_db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns
mob_makedummymobdb(0); //The first time this is invoked, it creates the dummy mob
- item_drop_ers = ers_new(sizeof(struct item_drop));
- item_drop_list_ers = ers_new(sizeof(struct item_drop_list));
+ item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE);
+ item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE);
mob_load();
diff --git a/src/map/npc.c b/src/map/npc.c
index 8d63f09c4..caaa9f601 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -3734,7 +3734,7 @@ int do_init_npc(void)
npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH);
npc_path_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,80);
- timer_event_ers = ers_new(sizeof(struct timer_event_data));
+ timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
// process all npc files
ShowStatus("Loading NPCs...\r");
diff --git a/src/map/pet.c b/src/map/pet.c
index c3fa41219..fbb25a1be 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -1349,8 +1349,8 @@ int do_init_pet(void)
{
read_petdb();
- item_drop_ers = ers_new(sizeof(struct item_drop));
- item_drop_list_ers = ers_new(sizeof(struct item_drop_list));
+ item_drop_ers = ers_new(sizeof(struct item_drop),"pet.c::item_drop_ers",ERS_OPT_NONE);
+ item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"pet.c::item_drop_list_ers",ERS_OPT_NONE);
add_timer_func_list(pet_hungry,"pet_hungry");
add_timer_func_list(pet_ai_hard,"pet_ai_hard");
diff --git a/src/map/skill.c b/src/map/skill.c
index 52fec7d52..95570eda6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -17545,8 +17545,8 @@ int do_init_skill (void)
skillunit_db = idb_alloc(DB_OPT_BASE);
skillcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA);
- skill_unit_ers = ers_new(sizeof(struct skill_unit_group));
- skill_timer_ers = ers_new(sizeof(struct skill_timerskill));
+ skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
+ skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
add_timer_func_list(skill_unit_timer,"skill_unit_timer");
add_timer_func_list(skill_castend_id,"skill_castend_id");
diff --git a/src/map/status.c b/src/map/status.c
index 98fc82206..bc25b124e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -10939,7 +10939,7 @@ int do_init_status(void)
status_readdb();
status_calc_sigma();
natural_heal_prev_tick = gettick();
- sc_data_ers = ers_new(sizeof(struct status_change_entry));
+ sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
return 0;
}