]> git.mxchange.org Git - flightgear.git/commitdiff
Nuked the segfault on exit bug everyone was seeing. The material lib could
authorcurt <curt>
Fri, 13 Jul 2001 05:15:29 +0000 (05:15 +0000)
committercurt <curt>
Fri, 13 Jul 2001 05:15:29 +0000 (05:15 +0000)
have multiple ptrs to individual entries (aliases) but the destructor was
trying to delete every ptr so it would delete already freed memory for aliases.
I implimented a simple ref counting scheme (similar to the plib mechanism) to
track references to material lib entries and only "delete" them when the last
reference is removed.

src/Objects/matlib.cxx
src/Objects/newmat.cxx
src/Objects/newmat.hxx

index 7103d976eeeee9188ca6a51c16884bfbda6a9d86..9d110bd692d762b0fc86cfec8882faba095b882d 100644 (file)
@@ -72,18 +72,6 @@ static bool local_file_exists( const string& path ) {
     } else {
        return true;
     }
-
-#if 0
-    cout << path << " ";
-    FILE *fp = fopen( path.c_str(), "r" );
-    if ( fp == NULL ) {
-       cout << " doesn't exist\n";
-       return false;
-    } else {
-       cout << " exists\n";
-       return true;
-    }
-#endif
 }
 
 
@@ -123,6 +111,7 @@ bool FGMaterialLib::load( const string& mpath ) {
            FGNewMat *m = matlib[src_mat];
             if ( m != NULL ) {
                 matlib[dst_mat] = m;
+               m->ref();
             } else {
                 SG_LOG( SG_GENERAL, SG_ALERT,
                         "Bad material alias pointing to nonexistant material" );
@@ -139,6 +128,7 @@ bool FGMaterialLib::load( const string& mpath ) {
                 // create a pointer to a heap allocated copy of the structure
                FGNewMat *m = new FGNewMat;
                 *m = tmp;
+               m->ref();
 
                // build the ssgSimpleState
                SGPath tex_path( globals->get_fg_root() );
@@ -277,9 +267,9 @@ FGMaterialLib::~FGMaterialLib ( void ) {
     // Free up all the material entries first
     for ( material_map_iterator it = begin(); it != end(); it++ ) {
        FGNewMat *slot = it->second;
-        if ( slot != NULL ) {
+       slot->deRef();
+       if ( slot->getRef() <= 0 ) {
             delete slot;
-           it->second = NULL;
         }
     }
 }
index 2fa702d61907d1ef04880f359ab9ff09a9a5c128..451b344ef59bf37c024834ac175afe283745b556 100644 (file)
@@ -43,6 +43,7 @@ FGNewMat::FGNewMat ( void ) {
     wrapu = wrapv = 1;
     mipmap = 1;
     light_coverage = -1.0;
+    refcount = 0;
 }
 
 
@@ -67,6 +68,7 @@ FGNewMat::FGNewMat ( const string &mat_name, const string &tex_name )
     specular[0] = specular[1] = specular[2] = specular[3] = 1.0;
     emission[0] = emission[1] = emission[2] = emission[3] = 1.0;
     light_coverage = -1.0;
+    refcount = 0;
 }
 
 
index acd9169bed0bdff875590824db086cbf404914ab..72a92ecc3232815d5cbfb9cdf3406e91cfa80749 100644 (file)
@@ -92,6 +92,10 @@ private:
     // true if texture loading deferred, and not yet loaded
     bool texture_loaded;
 
+    // ref count so we can properly delete if we have multiple
+    // pointers to this record
+    int refcount;
+
 public:
 
     // Constructor
@@ -144,6 +148,10 @@ public:
 
     inline ssgStateSelector *get_state() const { return state; }
 
+    inline void ref() { refcount++; }
+    inline void deRef() { refcount--; }
+    inline int getRef() const { return refcount; }
+
     void dump_info();
 };