From 79f3d7617fa1d4bc4b4b864330f184f93511c7f2 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 4 Feb 2020 18:06:29 -0800 Subject: [PATCH] Implement SafeTensorflowHandle with extensions --- .../Util/SafeHandleExtensions.cs | 54 +++++++++++++++++++ .../Util/SafeHandleLease.cs | 36 +++++++++++++ .../Util/SafeTensorflowHandle.cs | 43 +++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs create mode 100644 src/TensorFlowNET.Core/Util/SafeHandleLease.cs create mode 100644 src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs diff --git a/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs b/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs new file mode 100644 index 00000000..dca0bac3 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs @@ -0,0 +1,54 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + internal static class SafeHandleExtensions + { + /// + /// Acquires a lease on a safe handle. This method is intended to be used in the initializer of a using + /// statement. + /// + /// The to lease. + /// A , which must be disposed to release the resource. + /// If the lease could not be acquired. + public static SafeHandleLease Lease(this SafeHandle handle) + { + if (handle is null) + throw new ArgumentNullException(nameof(handle)); + + var success = false; + try + { + handle.DangerousAddRef(ref success); + if (!success) + throw new ObjectDisposedException(handle.GetType().FullName); + + return new SafeHandleLease(handle); + } + catch + { + if (success) + handle.DangerousRelease(); + + throw; + } + } + } +} diff --git a/src/TensorFlowNET.Core/Util/SafeHandleLease.cs b/src/TensorFlowNET.Core/Util/SafeHandleLease.cs new file mode 100644 index 00000000..dcc0e846 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeHandleLease.cs @@ -0,0 +1,36 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + /// + /// Represents a lease of a . + /// + /// + public readonly struct SafeHandleLease : IDisposable + { + private readonly SafeHandle _handle; + + internal SafeHandleLease(SafeHandle handle) + => _handle = handle; + + public void Dispose() + => _handle?.DangerousRelease(); + } +} \ No newline at end of file diff --git a/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs b/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs new file mode 100644 index 00000000..abfb3446 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs @@ -0,0 +1,43 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + public abstract class SafeTensorflowHandle : SafeHandle + { + private protected SafeTensorflowHandle() + : base(IntPtr.Zero, ownsHandle: true) + { + } + + private protected SafeTensorflowHandle(IntPtr handle) + : base(IntPtr.Zero, ownsHandle: true) + { + SetHandle(handle); + } + + private protected SafeTensorflowHandle(IntPtr handle, bool ownsHandle) + : base(IntPtr.Zero, ownsHandle) + { + SetHandle(handle); + } + + public override bool IsInvalid => handle == IntPtr.Zero; + } +}