Quantcast
Channel: .NET Framework Class Libraries forum
Viewing all articles
Browse latest Browse all 8156

CUDA SafeHandle ObjectDisposedException when exiting application

$
0
0

I'm having trouble using the SafeHandle for my unmanaged P/Invokes using the CUDA library. My problem is following. I have created a CUDA P/Invoke library with two methods to create a CUDA context.

public static extern CUresult cuCtxCreate(out CUcontext pCtx, CUctx_flags Flags, CUdevice dev);
public static extern CUresult cuCtxDestroy(CUcontext ctx);

Then to ensure the handle is closed when it's not needed anymore I createsd a CUcontext derived from a SafeHandle:

 /// <summary>
    /// Cuda Context Handle
    /// </summary>
    [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
    [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
    public class CUcontext : SafeHandleZeroOrMinusOneIsInvalid
    {
        public CUcontext()
            : base(true)
        {
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        protected override bool ReleaseHandle()
        {
            try
            {
                if (!IsInvalid)
                {
                  CUDADriverAPI.cuCtxDestroy(this);
                }
            }
            catch
            {
                SetHandleAsInvalid();
            }

            return true;
        }
    }

Then I wrote a small tester to see if the CUDA context gets released when closing the application:

void Main()
{
    CUDADriverAPI.cuInit(0);

    // Get the device handle
    CUdevice aDeviceHandle = new CUdevice();
    CUDA.Assert(CUDADriverAPI.cuDeviceGet(ref aDeviceHandle, 0));

    CUcontext aContextHandle = null;

    // Create a context.
    CUDA.Assert(CUDADriverAPI.cuCtxCreate(
        out aContextHandle,
        CUctx_flags.CU_CTX_SCHED_AUTO | CUctx_flags.CU_CTX_MAP_HOST,
        aDeviceHandle
        ));
}    

The problem is that the ReleaseHandle of the SafeHandle gets called immediately after the last curly bracket which is OK. The problem is that the SafeHandle fires a ObjectDisposedException when calling cuCtxDestroy although the finalizer has not run before.

My question is what exactly happens on the last curly bracket. If some internal CUDA objects has been created which subsystem is responsible to clean it after the application has been closed. This behaviour must be similar to the FileStream mechanism or anything else that deals with SafeHandles. If haven't got the magic behind it.

One thing that came into my mind was that I use the same SafeHandle in the Create and Destroy method. In most of the examples a regular IntPtr was used. Maybe this is one of the problems since I don't know if the handle is marked as "destroyed" when I'm in the ReleaseHandle() method and I don't know if the marshaller will recognize this as object disposed.

Thank you Martin






Viewing all articles
Browse latest Browse all 8156

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>