changeset 27844:e06ce39f78ad

allow mlock to lock current dynamically loaded function (bug #57245) * pt-eval.cc (tree_evaluator::mlock): Simply forward to call_stack::mlock. * call-stack.h, call-stack.cc (call_stack::mlock): New function. Lock first user-defined or dynamically loaded function on the call stack. Silently skip the built-in Fmlock function. Warn if called from any other built-in function.
author John W. Eaton <jwe@octave.org>
date Mon, 16 Dec 2019 14:34:34 -0500
parents 48c77d47ea81
children 25f914321e7b
files libinterp/corefcn/call-stack.cc libinterp/corefcn/call-stack.h libinterp/parse-tree/pt-eval.cc
diffstat 3 files changed, 44 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.cc	Sun Dec 15 20:01:14 2019 +0100
+++ b/libinterp/corefcn/call-stack.cc	Mon Dec 16 14:34:34 2019 -0500
@@ -720,6 +720,41 @@
       pop ();
   }
 
+  void call_stack::mlock (void) const
+  {
+    if (m_cs.empty ())
+      error ("mlock: call stack is empty");
+
+    octave_function *fcn = nullptr;
+
+    size_t idx = size ();
+
+    while (--idx)
+      {
+        const stack_frame *elt = m_cs[idx];
+        fcn = elt->function ();
+
+        if (fcn)
+          {
+            if (fcn->is_builtin_function ())
+              {
+                if (fcn->name () == "mlock")
+                  continue;
+
+                warning ("mlock: locking built-in function has no effect");
+                return;
+              }
+
+            break;
+          }
+      }
+
+    if (! fcn)
+      error ("mlock: invalid use outside a function");
+
+    fcn->lock ();
+  }
+
   symbol_info_list call_stack::all_variables (void)
   {
     return m_cs[m_curr_frame]->all_variables ();
--- a/libinterp/corefcn/call-stack.h	Sun Dec 15 20:01:14 2019 +0100
+++ b/libinterp/corefcn/call-stack.h	Mon Dec 16 14:34:34 2019 -0500
@@ -255,6 +255,14 @@
 
     void clear (void);
 
+    // Lock current function.  Skip built-in functions (mlock is skipped
+    // silently; warn for others) and look for the first caller that is
+    // a user-defined (m-file) or dynamically loaded (.oct or .mex)
+    // function.  That allows the built-in Fmlock function to lock the
+    // calling function instead of locking istelf.
+
+    void mlock (void) const;
+
     symbol_info_list all_variables (void);
 
     std::list<symbol_record> glob (const std::string& pattern) const;
--- a/libinterp/parse-tree/pt-eval.cc	Sun Dec 15 20:01:14 2019 +0100
+++ b/libinterp/parse-tree/pt-eval.cc	Mon Dec 16 14:34:34 2019 -0500
@@ -1726,12 +1726,7 @@
 
   void tree_evaluator::mlock (void) const
   {
-    octave_function *fcn = m_call_stack.current ();
-
-    if (! fcn)
-      error ("mlock: invalid use outside a function");
-
-    fcn->lock ();
+    m_call_stack.mlock ();
   }
 
   octave_value