# HG changeset patch # User jwe # Date 1161363270 0 # Node ID c9f0839c583f86816e540888edb288e0f4afbcea # Parent b83e4f9540a0611d176bb6a8e7f3c40d55613d04 [project @ 2006-10-20 16:54:30 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2006-10-20 Paul Kienzle + + * ov-mex-fcn.h (octave_mex_function::atexit): New function. + (octave_mex_function::exit_fcn_ptr): New data member. + * ov-mex-fcn.cc (octave_mex_function::exit_fcn_ptr): New data member. + (octave_mex_function::octave_mex_function): Initialize it. + (octave_mex_function::~octave_mex_function): + If we have an exit function, call it. + +2006-10-20 John W. Eaton + + * variables.cc (delete_symbol_tables): New function. + * variables.h: Provide decl. + * toplev.cc (do_octave_atexit): Call it. + + * mex.cc (mex::mex): New arg, a pointer to the current mex function. + (mex::curr_mex_fcn): New data member. + (mex::current_mex_function): New function. + (mexAtExit): Set exit function pointer in current mex file object. + +2006-10-20 Paul Kienzle + + * mex.cc (enum callstyle): Delete enum definition. + (Fortran_mex, C_mex): Delete functions. + (call_mex): First arg is now bool. + * ov-mex-fcn.cc (call_mex): Fix decl to match new definition. + (Fortran_mex, C_mex): Delete decls. + (octave_mex_function::do_multi_index_op): Simplify call to call_mex. + 2006-10-20 John W. Eaton * lex.l (handle_identifier): If a command name is found, skip diff --git a/src/mex.cc b/src/mex.cc --- a/src/mex.cc +++ b/src/mex.cc @@ -19,6 +19,7 @@ #include "oct-map.h" #include "oct-obj.h" #include "ov.h" +#include "ov-mex-fcn.h" #include "ov-usr-fcn.h" #include "pager.h" #include "parse.h" @@ -1904,7 +1905,8 @@ { public: - mex (void) : memlist (), arraylist (), fname (0) { } + mex (octave_mex_function *f) + : curr_mex_fcn (f), memlist (), arraylist (), fname (0) { } ~mex (void) { @@ -2098,6 +2100,11 @@ arraylist.erase (p); } + octave_mex_function *current_mex_function (void) const + { + return curr_mex_fcn; + } + // 1 if error should be returned to MEX file, 0 if abort. int trap_feval_error; @@ -2109,6 +2116,9 @@ private: + // Pointer to the mex function that corresponds to this mex context. + octave_mex_function *curr_mex_fcn; + // List of memory resources that need to be freed upon exit. std::set memlist; @@ -2791,26 +2801,10 @@ typedef void (*cmex_fptr) (int nlhs, mxArray **plhs, int nrhs, mxArray **prhs); typedef F77_RET_T (*fmex_fptr) (int& nlhs, mxArray **plhs, int& nrhs, mxArray **prhs); -enum callstyle { use_fortran, use_C }; - octave_value_list -call_mex (callstyle cs, void *f, const octave_value_list& args, int nargout) +call_mex (bool have_fmex, void *f, const octave_value_list& args, + int nargout, octave_mex_function *curr_mex_fcn) { -#if 0 - // Don't bother trapping stop/exit - // FIXME -- should really push "mex_exit" onto the octave - // atexit stack before we start and pop it when we are through, but - // the stack handle isn't exported from toplev.cc, so we can't. mex_exit - // would have to be declared as DEFUN(mex_exit,,,"") of course. - static bool unregistered = true; - - if (unregistered) - { - atexit (mex_exit); - unregistered = false; - } -#endif - // Use at least 1 for nargout since even for zero specified args, // still want to be able to return an ans. @@ -2829,7 +2823,7 @@ // Save old mex pointer. unwind_protect_ptr (mex_context); - mex context; + mex context (curr_mex_fcn); unwind_protect::add (mex::cleanup, static_cast (&context)); @@ -2840,7 +2834,7 @@ { mex_context = &context; - if (cs == use_fortran) + if (have_fmex) { fmex_fptr fcn = FCN_PTR_CAST (fmex_fptr, f); @@ -2881,18 +2875,6 @@ return retval; } -octave_value_list -Fortran_mex (void *f, const octave_value_list& args, int nargout) -{ - return call_mex (use_fortran, f, args, nargout); -} - -octave_value_list -C_mex (void *f, const octave_value_list& args, int nargout) -{ - return call_mex (use_C, f, args, nargout); -} - // C interface to mex functions: const char * @@ -3128,10 +3110,17 @@ } int -mexAtExit (void (*/*f*/) (void)) +mexAtExit (void (*f) (void)) { - // FIXME - error ("mexAtExit: not implemented"); + if (mex_context) + { + octave_mex_function *curr_mex_fcn = mex_context->current_mex_function (); + + assert (curr_mex_fcn); + + curr_mex_fcn->atexit (f); + } + return 0; } diff --git a/src/ov-mex-fcn.cc b/src/ov-mex-fcn.cc --- a/src/ov-mex-fcn.cc +++ b/src/ov-mex-fcn.cc @@ -44,7 +44,8 @@ octave_mex_function::octave_mex_function (void *fptr, bool fmex, const octave_shlib& shl, const std::string& nm) - : octave_function (nm), mex_fcn_ptr (fptr), have_fmex (fmex), sh_lib (shl) + : octave_function (nm), mex_fcn_ptr (fptr), exit_fcn_ptr (0), + have_fmex (fmex), sh_lib (shl) { mark_fcn_file_up_to_date (time_parsed ()); @@ -57,6 +58,9 @@ octave_mex_function::~octave_mex_function (void) { + if (exit_fcn_ptr) + (*exit_fcn_ptr) (); + octave_dynamic_loader::remove (my_name, sh_lib); } @@ -118,10 +122,8 @@ } extern octave_value_list -C_mex (void *f, const octave_value_list& args, int nargout); - -extern octave_value_list -Fortran_mex (void *f, const octave_value_list& args, int nargout); +call_mex (bool have_fmex, void *f, const octave_value_list& args, + int nargout, octave_mex_function *curr_mex_fcn); octave_value_list octave_mex_function::do_multi_index_op (int nargout, @@ -142,9 +144,7 @@ unwind_protect::add (octave_call_stack::unwind_pop, 0); - retval = have_fmex - ? Fortran_mex (mex_fcn_ptr, args, nargout) - : C_mex (mex_fcn_ptr, args, nargout); + retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this); unwind_protect::run_frame ("mex_func_eval"); } diff --git a/src/ov-mex-fcn.h b/src/ov-mex-fcn.h --- a/src/ov-mex-fcn.h +++ b/src/ov-mex-fcn.h @@ -81,10 +81,14 @@ octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); + void atexit (void (*fcn) (void)) { exit_fcn_ptr = fcn; } + private: void *mex_fcn_ptr; + void (*exit_fcn_ptr) (void); + bool have_fmex; octave_shlib sh_lib; diff --git a/src/toplev.cc b/src/toplev.cc --- a/src/toplev.cc +++ b/src/toplev.cc @@ -617,6 +617,11 @@ { deja_vu = true; + // Do this explicitly so that destructors for mex file objects + // are called, so that functions registered with mexAtExit are + // called. + delete_symbol_tables (); + command_editor::restore_terminal_state (); // FIXME -- is this needed? Can it cause any trouble? diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -104,6 +104,14 @@ curr_caller_sym_tab = curr_sym_tab = top_level_sym_tab; } +void +delete_symbol_tables (void) +{ + delete fbi_sym_tab; + delete global_sym_tab; + delete top_level_sym_tab; +} + // Attributes of variables and functions. // Is this a command-style function? diff --git a/src/variables.h b/src/variables.h --- a/src/variables.h +++ b/src/variables.h @@ -48,6 +48,7 @@ extern bool at_top_level (void); extern void initialize_symbol_tables (void); +extern void delete_symbol_tables (void); extern bool is_command_name (const std::string&);