예제 #1
0
        /// <summary>
        /// Sets the thread exit callback.
        /// </summary>
        private static unsafe int SetThreadExitCallbackMacOs(IntPtr callbackPtr)
        {
            int tlsIndex;
            var res = NativeMethodsMacOs.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr);

            CheckResult(res);

            return(tlsIndex);
        }
예제 #2
0
        /// <summary>
        /// Sets the thread exit callback, and returns an id to pass to <see cref="EnableCurrentThreadExitEvent"/>.
        /// </summary>
        /// <param name="callbackPtr">
        /// Pointer to a callback function that matches <see cref="ThreadExitCallback"/>.
        /// Get this pointer with <see cref="Marshal.GetFunctionPointerForDelegate"/> method; make sure that passed
        /// delegate is not garbage-collected (put it to a static property, for example).
        /// </param>
        /// <returns>Callback ID.</returns>
        public static unsafe int SetThreadExitCallback(IntPtr callbackPtr)
        {
            if (callbackPtr == IntPtr.Zero)
            {
                throw new ArgumentException("Should not be Zero", nameof(callbackPtr));
            }

            if (Os.IsWindows)
            {
                var res = NativeMethodsWindows.FlsAlloc(callbackPtr);

                if (res == NativeMethodsWindows.FLS_OUT_OF_INDEXES)
                {
                    throw new InvalidOperationException("FlsAlloc failed: " + Marshal.GetLastWin32Error());
                }

                return(res);
            }

            if (Os.IsMacOs)
            {
                int tlsIndex;
                var res = NativeMethodsMacOs.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr);

                NativeMethodsLinux.CheckResult(res);

                return(tlsIndex);
            }

            if (Os.IsLinux)
            {
                int tlsIndex;
                var res = NativeMethodsLinux.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr);

                NativeMethodsLinux.CheckResult(res);

                return(tlsIndex);
            }

            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
        }