forked from 0ad/0ad
adts: DynHashTbl: safely handle calling clear() right before dtor
vfs: remove second call to tree_init (now done by vfs_mount) vfs_tree: fix memory leak due to not destroying root node. commented and armor-plated things while at it. This was SVN commit r3647.
This commit is contained in:
parent
0a1077bdbd
commit
7564827a8a
@ -115,8 +115,13 @@ public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
free(tbl);
|
||||
tbl = 0;
|
||||
// note: users might call clear() right before the dtor runs,
|
||||
// so safely handling calling this twice.
|
||||
if(tbl)
|
||||
{
|
||||
free(tbl);
|
||||
tbl = 0;
|
||||
}
|
||||
num_entries = 0;
|
||||
// rationale: must not set to 0 because expand_tbl only doubles the size.
|
||||
// don't keep the previous size because it may have become huge and
|
||||
|
@ -782,7 +782,6 @@ void vfs_display()
|
||||
// splitting this into a separate function.
|
||||
static void vfs_init_once(void)
|
||||
{
|
||||
tree_init();
|
||||
mount_init();
|
||||
}
|
||||
|
||||
@ -805,5 +804,4 @@ void vfs_shutdown()
|
||||
{
|
||||
trace_shutdown();
|
||||
mount_shutdown();
|
||||
tree_shutdown();
|
||||
}
|
||||
|
@ -617,7 +617,6 @@ LibError vfs_mount(const char* V_mount_point, const char* P_real_path, int flags
|
||||
LibError mount_rebuild()
|
||||
{
|
||||
tree_clear();
|
||||
tree_init();
|
||||
remount_all();
|
||||
return ERR_OK;
|
||||
}
|
||||
@ -677,7 +676,7 @@ void mount_init()
|
||||
|
||||
void mount_shutdown()
|
||||
{
|
||||
tree_clear();
|
||||
tree_shutdown();
|
||||
mount_unmount_all();
|
||||
}
|
||||
|
||||
|
@ -420,30 +420,39 @@ static LibError lookup(TDir* td, const char* path, uint flags, TNode** pnode)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// this is a pointer to node_alloc-ed memory instead of a static TDir for
|
||||
// 2 reasons:
|
||||
// - no NLSO shutdown order issues; validity is well defined
|
||||
// (namely between tree_init and tree_shutdown)
|
||||
// - bonus: tree_init can use it when checking if called twice.
|
||||
//
|
||||
//
|
||||
static TDir* tree_root;
|
||||
|
||||
// rationale: can't do this in tree_shutdown - we'd leak at exit.
|
||||
// calling from tree_add* is ugly as well, so require manual init.
|
||||
|
||||
// establish a root node and prepare node_allocator for use.
|
||||
//
|
||||
// rationale: calling this from every tree_add* is ugly, so require
|
||||
// manual init.
|
||||
void tree_init()
|
||||
{
|
||||
// must not call more than once without intervening tree_shutdown
|
||||
debug_assert(!tree_root);
|
||||
|
||||
node_init();
|
||||
|
||||
#include "nommgr.h" // placement new
|
||||
void* mem = node_alloc();
|
||||
if(mem)
|
||||
{
|
||||
#include "nommgr.h"
|
||||
tree_root = new(mem) TDir("", "");
|
||||
#include "mmgr.h"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tree_shutdown()
|
||||
{
|
||||
node_shutdown();
|
||||
}
|
||||
|
||||
|
||||
// empty all directories and free their memory.
|
||||
// however, node_allocator's DynArray still remains initialized and
|
||||
// the root directory is usable (albeit empty).
|
||||
// use when remounting.
|
||||
void tree_clear()
|
||||
{
|
||||
tree_root->clearR();
|
||||
@ -451,6 +460,26 @@ void tree_clear()
|
||||
}
|
||||
|
||||
|
||||
// shut down entirely; destroys node_allocator. any further use after this
|
||||
// requires another tree_init.
|
||||
void tree_shutdown()
|
||||
{
|
||||
// tree_shutdown should be preceded by tree_init, so ought to be valid.
|
||||
debug_assert(tree_root);
|
||||
|
||||
// careful! do not call tree_clear because it will un-map all
|
||||
// node memory, which would cause the dtor below to fail.
|
||||
tree_root->clearR();
|
||||
|
||||
// we've still got to destroy the root node (otherwise its
|
||||
// hash table will leak).
|
||||
tree_root->~TDir();
|
||||
tree_root = 0;
|
||||
|
||||
node_shutdown();
|
||||
}
|
||||
|
||||
|
||||
// write a representation of the VFS tree to stdout.
|
||||
void tree_display()
|
||||
{
|
||||
|
@ -26,14 +26,19 @@ class TDir;
|
||||
#include "vfs_mount.h" // Mount
|
||||
|
||||
|
||||
|
||||
// establish a root node and prepare node_allocator for use.
|
||||
extern void tree_init();
|
||||
|
||||
// shut down entirely; destroys node_allocator. any further use after this
|
||||
// requires another tree_init.
|
||||
extern void tree_shutdown();
|
||||
|
||||
extern void tree_display();
|
||||
|
||||
// empties the tree and frees all resources. this is used when
|
||||
// rebuilding VFS and on exit.
|
||||
// empty all directories and free their memory.
|
||||
// however, node_allocator's DynArray still remains initialized and
|
||||
// the root directory is usable (albeit empty).
|
||||
// use when remounting.
|
||||
extern void tree_clear();
|
||||
|
||||
extern time_t tree_most_recent_mtime();
|
||||
|
Loading…
Reference in New Issue
Block a user