changeset 7179:32abf21b21e9

[project @ 2007-11-15 02:44:05 by jwe]
author jwe
date Thu, 15 Nov 2007 02:44:06 +0000
parents 8cfdb0f24f41
children 55ff2d9a27c7
files src/ChangeLog src/mex.cc
diffstat 2 files changed, 62 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Nov 14 22:30:28 2007 +0000
+++ b/src/ChangeLog	Thu Nov 15 02:44:06 2007 +0000
@@ -1,3 +1,13 @@
+2007-11-14  John W. Eaton  <jwe@octave.org>
+
+	* mex.cc (mex::foreign_memlist): New data member.
+	(mex::mark_foreign, mex::unmark_foreign): New functions.
+	(mex::free): Don't warn about pointers found in foreign_memlist.
+	(maybe_mark_foreign): New function.
+	(mxArray_octave_value::get_data, mxArray_octave_value::get_ir,
+	mxArray_octave_value::get_jc):
+	Call maybe_mark_foreign on returned pointer.
+
 2007-11-14  David Bateman  <dbateman@free.fr>
 
 	* mex.cc (mxArray_sparse::mxArray_sparse (const mxArray_sparse&)):
--- a/src/mex.cc	Wed Nov 14 22:30:28 2007 +0000
+++ b/src/mex.cc	Thu Nov 15 02:44:06 2007 +0000
@@ -282,6 +282,8 @@
 // happens, we delete this representation, so the conversion can only
 // happen once per call to a MEX file.
 
+static inline void *maybe_mark_foreign (void *ptr);
+
 class mxArray_octave_value : public mxArray_base
 {
 public:
@@ -467,7 +469,7 @@
 
     if (is_char ()
 	|| (is_numeric () && is_real_type () && ! is_range ()))
-      retval = val.mex_get_data ();
+      retval = maybe_mark_foreign (val.mex_get_data ());
     else
       request_mutation ();
 
@@ -494,12 +496,12 @@
 
   mwIndex *get_ir (void) const
   {
-    return val.mex_get_ir ();
+    return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_ir ()));
   }
 
   mwIndex *get_jc (void) const
   {
-    return val.mex_get_jc ();
+    return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_jc ()));
   }
 
   mwSize get_nzmax (void) const { return val.nzmax (); }
@@ -2175,7 +2177,14 @@
 	    xfree (ptr);
 	  }
 	else
-	  warning ("mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
+	  {
+	    p = foreign_memlist.find (ptr);
+
+	    if (p != foreign_memlist.end ())
+	      foreign_memlist.erase (p);
+	    else
+	      warning ("mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
+	  }
       }
   }
 
@@ -2218,6 +2227,31 @@
       arraylist.erase (p);
   }
 
+  // Mark a pointer as one we allocated.
+  void mark_foreign (void *ptr)
+  {
+#ifdef DEBUG
+    if (foreign_memlist.find (ptr) != foreign_memlist.end ())
+      warning ("%s: double registration ignored", function_name ());
+#endif
+
+    foreign_memlist.insert (ptr);
+  }
+
+  // Unmark a pointer as one we allocated.
+  void unmark_foreign (void *ptr)
+  {
+    std::set<void *>::iterator p = foreign_memlist.find (ptr);
+
+    if (p != foreign_memlist.end ())
+      foreign_memlist.erase (p);
+#ifdef DEBUG
+    else
+      warning ("%s: value not marked", function_name ());
+#endif
+
+  }
+
   // Make a new array value and initialize from an octave value; it will be
   // freed on exit unless marked as persistent.
   mxArray *make_value (const octave_value& ov)
@@ -2268,8 +2302,13 @@
   // List of memory resources that need to be freed upon exit.
   std::set<void *> memlist;
 
+  // List of mxArray objects that need to be freed upon exit.
   std::set<mxArray *> arraylist;
 
+  // List of memory resources we know about, but that were allocated
+  // elsewhere.
+  std::set<void *> foreign_memlist;
+
   // The name of the currently executing function.
   mutable char *fname;
 
@@ -2320,6 +2359,15 @@
   return mex_context ? mex_context->calloc_unmarked (n, t) : ::calloc (n, t);
 }
 
+static inline void *
+maybe_mark_foreign (void *ptr)
+{
+  if (mex_context)
+    mex_context->mark_foreign (ptr);
+
+  return ptr;
+}
+
 static inline mxArray *
 maybe_unmark_array (mxArray *ptr)
 {