# HG changeset patch # User jwe # Date 1195094646 0 # Node ID 32abf21b21e9367c53004780d0d26228671eb7ac # Parent 8cfdb0f24f41c4b3397be0873d68eb5f2947b58c [project @ 2007-11-15 02:44:05 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2007-11-14 John W. Eaton + + * 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 * mex.cc (mxArray_sparse::mxArray_sparse (const mxArray_sparse&)): diff --git a/src/mex.cc b/src/mex.cc --- a/src/mex.cc +++ b/src/mex.cc @@ -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 (maybe_mark_foreign (val.mex_get_ir ())); } mwIndex *get_jc (void) const { - return val.mex_get_jc (); + return static_cast (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::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 memlist; + // List of mxArray objects that need to be freed upon exit. std::set arraylist; + // List of memory resources we know about, but that were allocated + // elsewhere. + std::set 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) {