EndAllowThreads() public static method

EndAllowThreads Method
Re-aquire the Python global interpreter lock for the current thread. This is equivalent to the Py_END_ALLOW_THREADS macro provided by the C Python API. For more information, see the "Extending and Embedding" section of the Python documentation on www.python.org.
public static EndAllowThreads ( IntPtr ts ) : void
ts System.IntPtr
return void
Beispiel #1
0
 public void Collect(bool forceDispose = true)
 {
     if (Instance._finalizerTask != null &&
         !Instance._finalizerTask.IsCompleted)
     {
         var ts = PythonEngine.BeginAllowThreads();
         Instance._finalizerTask.Wait();
         PythonEngine.EndAllowThreads(ts);
     }
     else if (forceDispose)
     {
         Instance.DisposeAll();
     }
 }
        internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, Type type, MethodBase info, MethodInfo[] methodinfo)
        {
            List <Binding> bindings = Bind(inst, args, kw, type, info, methodinfo);
            object         result   = null;
            IntPtr         ts       = IntPtr.Zero;

            if (bindings.Count == 0)
            {
                var value = "No method matches given arguments";
                if (methodinfo != null && methodinfo.Length > 0)
                {
                    value += $" for {methodinfo[0].Name}";
                }
                Exceptions.SetError(Exceptions.TypeError, value);
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                ts = PythonEngine.BeginAllowThreads();
            }

            #region COM Binding

            Binding   binding = null;
            Exception ex      = new Exception();

            foreach (Binding bind in bindings)
            {
                if (binding != null)
                {
                    break;
                }

                try
                {
                    result  = bind.info.Invoke(bind.inst, BindingFlags.Default, null, bind.args, null);
                    binding = bind;
                }
                catch (TargetInvocationException e)
                {
                    System.Diagnostics.Debug.WriteLine("TargetInvocationException: " + bind.info.Name + " with " + bind.args.Length + " arguments.");
                    binding = null;
                    ex      = e;
                }
                catch (Exception e)
                {
                    binding = null;
                    ex      = e;
                }
            }


            if (binding == null)
            {
                if (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }
                if (allow_threads)
                {
                    PythonEngine.EndAllowThreads(ts);
                }
                Exceptions.SetError(ex);

                return(IntPtr.Zero);
            }

            #endregion

            if (allow_threads)
            {
                PythonEngine.EndAllowThreads(ts);
            }

            // If there are out parameters, we return a tuple containing
            // the result followed by the out parameters. If there is only
            // one out parameter and the return type of the method is void,
            // we return the out parameter as the result to Python (for
            // code compatibility with ironpython).

            var mi = (MethodInfo)binding.info;

            if (binding.outs == 1 && mi.ReturnType == typeof(void))
            {
            }

            if (binding.outs > 0)
            {
                ParameterInfo[] pi = mi.GetParameters();
                int             c  = pi.Length;
                var             n  = 0;

                IntPtr t = Runtime.PyTuple_New(binding.outs + 1);
                IntPtr v = Converter.ToPython(result, mi.ReturnType);
                Runtime.PyTuple_SetItem(t, n, v);
                n++;

                for (var i = 0; i < c; i++)
                {
                    Type pt = pi[i].ParameterType;
                    if (pi[i].IsOut || pt.IsByRef)
                    {
                        v = Converter.ToPython(binding.args[i], pt);
                        Runtime.PyTuple_SetItem(t, n, v);
                        n++;
                    }
                }

                if (binding.outs == 1 && mi.ReturnType == typeof(void))
                {
                    v = Runtime.PyTuple_GetItem(t, 1);
                    Runtime.XIncref(v);
                    Runtime.XDecref(t);
                    return(v);
                }

                return(t);
            }

            return(Converter.ToPython(result, mi.ReturnType));
        }
Beispiel #3
0
        internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
        {
            // No valid methods, nothing to bind.
            if (GetMethods().Length == 0)
            {
                var msg = new StringBuilder("The underlying C# method(s) have been deleted");
                if (list.Count > 0 && list[0].Name != null)
                {
                    msg.Append($": {list[0]}");
                }
                return(Exceptions.RaiseTypeError(msg.ToString()));
            }

            Binding binding = Bind(inst, args, kw, info, methodinfo);
            object  result;
            IntPtr  ts = IntPtr.Zero;

            if (binding == null)
            {
                var value = new StringBuilder("No method matches given arguments");
                if (methodinfo != null && methodinfo.Length > 0)
                {
                    value.Append($" for {methodinfo[0].Name}");
                }
                else if (list.Count > 0 && list[0].Valid)
                {
                    value.Append($" for {list[0].Value.Name}");
                }

                value.Append(": ");
                Runtime.PyErr_Fetch(out var errType, out var errVal, out var errTrace);
                AppendArgumentTypes(to: value, args);
                Runtime.PyErr_Restore(errType.StealNullable(), errVal.StealNullable(), errTrace.StealNullable());
                Exceptions.RaiseTypeError(value.ToString());
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                ts = PythonEngine.BeginAllowThreads();
            }

            try
            {
                result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null);
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                if (allow_threads)
                {
                    PythonEngine.EndAllowThreads(ts);
                }
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                PythonEngine.EndAllowThreads(ts);
            }

            // If there are out parameters, we return a tuple containing
            // the result, if any, followed by the out parameters. If there is only
            // one out parameter and the return type of the method is void,
            // we return the out parameter as the result to Python (for
            // code compatibility with ironpython).

            var mi = (MethodInfo)binding.info;

            if (binding.outs > 0)
            {
                ParameterInfo[] pi = mi.GetParameters();
                int             c  = pi.Length;
                var             n  = 0;

                bool   isVoid    = mi.ReturnType == typeof(void);
                int    tupleSize = binding.outs + (isVoid ? 0 : 1);
                IntPtr t         = Runtime.PyTuple_New(tupleSize);
                if (!isVoid)
                {
                    IntPtr v = Converter.ToPython(result, mi.ReturnType);
                    Runtime.PyTuple_SetItem(t, n, v);
                    n++;
                }

                for (var i = 0; i < c; i++)
                {
                    Type pt = pi[i].ParameterType;
                    if (pt.IsByRef)
                    {
                        IntPtr v = Converter.ToPython(binding.args[i], pt.GetElementType());
                        Runtime.PyTuple_SetItem(t, n, v);
                        n++;
                    }
                }

                if (binding.outs == 1 && mi.ReturnType == typeof(void))
                {
                    IntPtr v = Runtime.PyTuple_GetItem(t, 0);
                    Runtime.XIncref(v);
                    Runtime.XDecref(t);
                    return(v);
                }

                return(t);
            }

            return(Converter.ToPython(result, mi.ReturnType));
        }
Beispiel #4
0
        internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
        {
            Binding binding = Bind(inst, args, kw, info, methodinfo);
            object  result;
            IntPtr  ts = IntPtr.Zero;

            if (binding == null)
            {
                var value = new StringBuilder("No method matches given arguments");
                if (methodinfo != null && methodinfo.Length > 0)
                {
                    value.Append($" for {methodinfo[0].Name}");
                }

                value.Append(": ");
                AppendArgumentTypes(to: value, args);
                Exceptions.SetError(Exceptions.TypeError, value.ToString());
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                ts = PythonEngine.BeginAllowThreads();
            }

            try
            {
                result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null);
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                if (allow_threads)
                {
                    PythonEngine.EndAllowThreads(ts);
                }
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                PythonEngine.EndAllowThreads(ts);
            }

            // If there are out parameters, we return a tuple containing
            // the result followed by the out parameters. If there is only
            // one out parameter and the return type of the method is void,
            // we return the out parameter as the result to Python (for
            // code compatibility with ironpython).

            var mi = (MethodInfo)binding.info;

            if (binding.outs == 1 && mi.ReturnType == typeof(void))
            {
            }

            if (binding.outs > 0)
            {
                ParameterInfo[] pi = mi.GetParameters();
                int             c  = pi.Length;
                var             n  = 0;

                IntPtr t = Runtime.PyTuple_New(binding.outs + 1);
                IntPtr v = Converter.ToPython(result, mi.ReturnType);
                Runtime.PyTuple_SetItem(t, n, v);
                n++;

                for (var i = 0; i < c; i++)
                {
                    Type pt = pi[i].ParameterType;
                    if (pi[i].IsOut || pt.IsByRef)
                    {
                        v = Converter.ToPython(binding.args[i], pt);
                        Runtime.PyTuple_SetItem(t, n, v);
                        n++;
                    }
                }

                if (binding.outs == 1 && mi.ReturnType == typeof(void))
                {
                    v = Runtime.PyTuple_GetItem(t, 1);
                    Runtime.XIncref(v);
                    Runtime.XDecref(t);
                    return(v);
                }

                return(t);
            }

            return(Converter.ToPython(result, mi.ReturnType));
        }
Beispiel #5
0
        internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
        {
            Binding binding = Bind(inst, args, kw, info, methodinfo);
            object  result;
            IntPtr  ts = IntPtr.Zero;

            if (binding == null)
            {
                var value = new StringBuilder("No method matches given arguments");
                if (methodinfo != null && methodinfo.Length > 0)
                {
                    value.Append($" for {methodinfo[0].Name}");
                }

                long argCount = Runtime.PyTuple_Size(args);
                value.Append(": (");
                for (long argIndex = 0; argIndex < argCount; argIndex++)
                {
                    var arg = Runtime.PyTuple_GetItem(args, argIndex);
                    if (arg != IntPtr.Zero)
                    {
                        var type = Runtime.PyObject_Type(arg);
                        if (type != IntPtr.Zero)
                        {
                            try {
                                var description = Runtime.PyObject_Unicode(type);
                                if (description != IntPtr.Zero)
                                {
                                    value.Append(Runtime.GetManagedString(description));
                                    Runtime.XDecref(description);
                                }
                            } finally {
                                Runtime.XDecref(type);
                            }
                        }
                    }

                    if (argIndex + 1 < argCount)
                    {
                        value.Append(", ");
                    }
                }
                value.Append(')');
                Exceptions.SetError(Exceptions.TypeError, value.ToString());
                return(IntPtr.Zero);
            }

            //allow_threads = true breaks the code with passing pyobjects to clr functions.
            //I think this happens because python is not thread safe and objects cannot be called
            //different threads
            allow_threads = false;
            if (allow_threads)
            {
                Console.WriteLine("ALLOW THR");
                ts = PythonEngine.BeginAllowThreads();
            }

            try
            {
                result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null);
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                if (allow_threads)
                {
                    PythonEngine.EndAllowThreads(ts);
                }
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }

            if (allow_threads)
            {
                PythonEngine.EndAllowThreads(ts);
            }

            // If there are out parameters, we return a tuple containing
            // the result followed by the out parameters. If there is only
            // one out parameter and the return type of the method is void,
            // we return the out parameter as the result to Python (for
            // code compatibility with ironpython).

            var mi = (MethodInfo)binding.info;

            if (binding.outs == 1 && mi.ReturnType == typeof(void))
            {
            }

            if (binding.outs > 0)
            {
                ParameterInfo[] pi = mi.GetParameters();
                int             c  = pi.Length;
                var             n  = 0;

                IntPtr t = Runtime.PyTuple_New(binding.outs + 1);
                IntPtr v = Converter.ToPython(result, mi.ReturnType);
                Runtime.PyTuple_SetItem(t, n, v);
                n++;

                for (var i = 0; i < c; i++)
                {
                    Type pt = pi[i].ParameterType;
                    if (pi[i].IsOut || pt.IsByRef)
                    {
                        v = Converter.ToPython(binding.args[i], pt);
                        Runtime.PyTuple_SetItem(t, n, v);
                        n++;
                    }
                }

                if (binding.outs == 1 && mi.ReturnType == typeof(void))
                {
                    v = Runtime.PyTuple_GetItem(t, 1);
                    Runtime.XIncref(v);
                    Runtime.XDecref(t);
                    return(v);
                }

                return(t);
            }


            if (mi.ReturnType == typeof(QuantApp.Kernel.JVM.JVMObject))
            {
                dynamic pymodule = Py.Import("clr");
                result = pymodule.createJVM(result);
            }

            return(Converter.ToPython(result, mi.ReturnType));
        }
Beispiel #6
0
        /// <summary>
        /// Descriptor __set__ implementation. This method sets the value of
        /// a property based on the given Python value. The Python value must
        /// be convertible to the type of the property.
        /// </summary>
        public new static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val)
        {
            var        self   = (PropertyObject)GetManagedObject(ds);
            MethodInfo setter = self.setter;
            object     newval;
            IntPtr     ts = IntPtr.Zero;

            if (val == IntPtr.Zero)
            {
                Exceptions.RaiseTypeError("cannot delete property");
                return(-1);
            }

            if (setter == null)
            {
                Exceptions.RaiseTypeError("property is read-only");
                return(-1);
            }


            if (!Converter.ToManaged(val, self.info.PropertyType, out newval, true))
            {
                return(-1);
            }

            bool is_static = setter.IsStatic;

            if (ob == IntPtr.Zero || ob == Runtime.PyNone)
            {
                if (!is_static)
                {
                    Exceptions.RaiseTypeError("instance property must be set on an instance");
                    return(-1);
                }
            }

            try
            {
                if (!is_static)
                {
                    var co = GetManagedObject(ob) as CLRObject;
                    if (co == null)
                    {
                        Exceptions.RaiseTypeError("invalid target");
                        return(-1);
                    }
                    ts = PythonEngine.BeginAllowThreads();
                    self.info.SetValue(co.inst, newval, null);
                }
                else
                {
                    ts = PythonEngine.BeginAllowThreads();
                    self.info.SetValue(null, newval, null);
                }
                PythonEngine.EndAllowThreads(ts);
                return(0);
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }

                if (IntPtr.Zero != ts)
                {
                    PythonEngine.EndAllowThreads(ts);
                }
                Exceptions.SetError(e);
                return(-1);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Descriptor __get__ implementation. This method returns the
        /// value of the property on the given object. The returned value
        /// is converted to an appropriately typed Python object.
        /// </summary>
        public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
        {
            var        self   = (PropertyObject)GetManagedObject(ds);
            MethodInfo getter = self.getter;
            object     result;

            IntPtr ts = IntPtr.Zero;

            if (getter == null)
            {
                return(Exceptions.RaiseTypeError("property cannot be read"));
            }

            if (ob == IntPtr.Zero || ob == Runtime.PyNone)
            {
                if (!getter.IsStatic)
                {
                    Exceptions.SetError(Exceptions.TypeError,
                                        "instance property must be accessed through a class instance");
                    return(IntPtr.Zero);
                }

                ts = PythonEngine.BeginAllowThreads();
                try
                {
                    result = self.info.GetValue(null, null);
                    PythonEngine.EndAllowThreads(ts);
                    return(Converter.ToPython(result, self.info.PropertyType));
                }
                catch (Exception e)
                {
                    PythonEngine.EndAllowThreads(ts);
                    return(Exceptions.RaiseTypeError(e.Message));
                }
            }

            var co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(Exceptions.RaiseTypeError("invalid target"));
            }

            ts = PythonEngine.BeginAllowThreads();
            try
            {
                result = self.info.GetValue(co.inst, null);
                PythonEngine.EndAllowThreads(ts);
                return(Converter.ToPython(result, self.info.PropertyType));
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                PythonEngine.EndAllowThreads(ts);
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }
        }
Beispiel #8
0
        internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw,
                                       MethodBase info)
        {
            Binding binding = this.Bind(inst, args, kw, info);
            Object  result;

            if (binding == null)
            {
                Exceptions.SetError(Exceptions.TypeError,
                                    "no method matches given arguments"
                                    );
                return(IntPtr.Zero);
            }

            IntPtr ts = PythonEngine.BeginAllowThreads();

            try {
                result = binding.info.Invoke(binding.inst,
                                             BindingFlags.Default,
                                             null,
                                             binding.args,
                                             null);
            }
            catch (Exception e) {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                PythonEngine.EndAllowThreads(ts);
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }

            PythonEngine.EndAllowThreads(ts);

            // If there are out parameters, we return a tuple containing
            // the result followed by the out parameters. If there is only
            // one out parameter and the return type of the method is void,
            // we return the out parameter as the result to Python (for
            // code compatibility with ironpython).

            MethodInfo mi = (MethodInfo)binding.info;

            if ((binding.outs == 1) && (mi.ReturnType == typeof(void)))
            {
            }

            if (binding.outs > 0)
            {
                ParameterInfo[] pi = mi.GetParameters();
                int             c  = pi.Length;
                int             n  = 0;

                IntPtr t = Runtime.PyTuple_New(binding.outs + 1);
                IntPtr v = Converter.ToPython(result, mi.ReturnType);
                Runtime.PyTuple_SetItem(t, n, v);
                n++;

                for (int i = 0; i < c; i++)
                {
                    Type pt = pi[i].ParameterType;
                    if (pi[i].IsOut || pt.IsByRef)
                    {
                        v = Converter.ToPython(binding.args[i], pt);
                        Runtime.PyTuple_SetItem(t, n, v);
                        n++;
                    }
                }

                if ((binding.outs == 1) && (mi.ReturnType == typeof(void)))
                {
                    v = Runtime.PyTuple_GetItem(t, 1);
                    Runtime.Incref(v);
                    Runtime.Decref(t);
                    return(v);
                }

                return(t);
            }

            return(Converter.ToPython(result, mi.ReturnType));
        }