Exemplo n.º 1
0
        /// <summary>
        /// Removes thread exit callback that has been set with <see cref="SetThreadExitCallback"/>.
        /// NOTE: callback may be called as a result of this method call on some platforms.
        /// </summary>
        /// <param name="callbackId">Callback id returned from <see cref="SetThreadExitCallback"/>.</param>
        public static void RemoveThreadExitCallback(int callbackId)
        {
            if (Os.IsWindows)
            {
                var res = NativeMethodsWindows.FlsFree(callbackId);

                if (!res)
                {
                    throw new InvalidOperationException("FlsFree failed: " + Marshal.GetLastWin32Error());
                }
            }
            else if (Os.IsMacOs)
            {
                var res = NativeMethodsMacOs.pthread_key_delete(callbackId);
                NativeMethodsLinux.CheckResult(res);
            }
            else if (Os.IsLinux)
            {
                var res = Os.IsMono
                    ? NativeMethodsMono.pthread_key_delete(callbackId)
                    : NativeMethodsLinux.pthread_key_delete(callbackId);

                NativeMethodsLinux.CheckResult(res);
            }
            else
            {
                throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Enables thread exit event for current thread.
        /// </summary>
        public static void EnableCurrentThreadExitEvent(int callbackId, IntPtr threadLocalValue)
        {
            Debug.Assert(threadLocalValue != IntPtr.Zero);

            // Store any value so that destructor callback is fired.
            if (Os.IsWindows)
            {
                var res = NativeMethodsWindows.FlsSetValue(callbackId, threadLocalValue);

                if (!res)
                {
                    throw new InvalidOperationException("FlsSetValue failed: " + Marshal.GetLastWin32Error());
                }
            }
            else if (Os.IsMacOs)
            {
                var res = NativeMethodsMacOs.pthread_setspecific(callbackId, threadLocalValue);
                NativeMethodsLinux.CheckResult(res);
            }
            else if (Os.IsLinux)
            {
                var res = Os.IsMono
                    ? NativeMethodsMono.pthread_setspecific(callbackId, threadLocalValue)
                    : NativeMethodsLinux.pthread_setspecific(callbackId, threadLocalValue);

                NativeMethodsLinux.CheckResult(res);
            }
            else
            {
                throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Loads specified DLL.
        /// </summary>
        /// <returns>Null when successful; error message otherwise.</returns>
        public static string Load(string dllPath)
        {
            if (Os.IsWindows)
            {
                return(NativeMethodsWindows.LoadLibrary(dllPath) == IntPtr.Zero
                    ? FormatWin32Error(Marshal.GetLastWin32Error()) ?? "Unknown error"
                    : null);
            }

            if (Os.IsLinux)
            {
                if (Os.IsMono)
                {
                    return(NativeMethodsMono.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
                        ? GetErrorText(NativeMethodsMono.dlerror())
                        : null);
                }

                if (Os.IsNetCore)
                {
                    return(NativeMethodsCore.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
                        ? GetErrorText(NativeMethodsCore.dlerror())
                        : null);
                }

                return(NativeMethodsLinux.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
                    ? GetErrorText(NativeMethodsLinux.dlerror())
                    : null);
            }

            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sets the thread exit callback.
        /// </summary>
        private static unsafe int SetThreadExitCallbackMono(IntPtr callbackPtr)
        {
            int tlsIndex;

            CheckResult(NativeMethodsMono.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr));

            return(tlsIndex);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Loads specified DLL.
        /// </summary>
        /// <returns>Library handle and error message.</returns>
        public static KeyValuePair <IntPtr, string> Load(string dllPath)
        {
            if (Os.IsWindows)
            {
                var ptr = NativeMethodsWindows.LoadLibrary(dllPath);
                return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                    ? FormatWin32Error(Marshal.GetLastWin32Error()) ?? "Unknown error"
                    : null));
            }

            if (Os.IsMacOs)
            {
                var ptr = NativeMethodsMacOs.dlopen(dllPath, RtldGlobal | RtldLazy);
                return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                    ? GetErrorText(NativeMethodsMacOs.dlerror())
                    : null));
            }

            if (Os.IsLinux)
            {
                if (Os.IsMono)
                {
                    var ptr = NativeMethodsMono.dlopen(dllPath, RtldGlobal | RtldLazy);
                    return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                        ? GetErrorText(NativeMethodsMono.dlerror())
                        : null));
                }

                // Depending on the Linux distro, dlopen is either present in libdl or in libcoreclr.
                try
                {
                    var ptr = NativeMethodsLinuxLibcoreclr.dlopen(dllPath, RtldGlobal | RtldLazy);
                    return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                        ? GetErrorText(NativeMethodsLinuxLibcoreclr.dlerror())
                        : null));
                }
                catch (EntryPointNotFoundException)
                {
                    var ptr = NativeMethodsLinuxLibdl.dlopen(dllPath, RtldGlobal | RtldLazy);
                    return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                        ? GetErrorText(NativeMethodsLinuxLibdl.dlerror())
                        : null));
                }
            }

            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Loads specified DLL.
        /// </summary>
        /// <returns>Library handle and error message.</returns>
        public static KeyValuePair <IntPtr, string> Load(string dllPath)
        {
            if (Os.IsWindows)
            {
                var ptr = NativeMethodsWindows.LoadLibrary(dllPath);
                return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                    ? FormatWin32Error(Marshal.GetLastWin32Error()) ?? "Unknown error"
                    : null));
            }

            if (Os.IsMacOs)
            {
                var ptr = NativeMethodsMacOs.dlopen(dllPath, RtldGlobal | RtldLazy);
                return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                    ? GetErrorText(NativeMethodsMacOs.dlerror())
                    : null));
            }

            if (Os.IsLinux)
            {
                if (Os.IsMono)
                {
                    var ptr = NativeMethodsMono.dlopen(dllPath, RtldGlobal | RtldLazy);
                    return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                        ? GetErrorText(NativeMethodsMono.dlerror())
                        : null));
                }

                if (Os.IsNetCore)
                {
                    var ptr = NativeMethodsCore.dlopen(dllPath, RtldGlobal | RtldLazy);
                    return(new KeyValuePair <IntPtr, string>(ptr, ptr == IntPtr.Zero
                        ? GetErrorText(NativeMethodsCore.dlerror())
                        : null));
                }

                var lptr = NativeMethodsLinux.dlopen(dllPath, RtldGlobal | RtldLazy);
                return(new KeyValuePair <IntPtr, string>(lptr, lptr == IntPtr.Zero
                    ? GetErrorText(NativeMethodsLinux.dlerror())
                    : null));
            }

            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
        }
Exemplo n.º 7
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"/>.
        /// </param>
        public static unsafe int SetThreadExitCallback(IntPtr callbackPtr)
        {
            Debug.Assert(callbackPtr != IntPtr.Zero);

            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 = Os.IsMono
                    ? NativeMethodsMono.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr)
                    : NativeMethodsLinux.pthread_key_create(new IntPtr(&tlsIndex), callbackPtr);

                NativeMethodsLinux.CheckResult(res);

                return(tlsIndex);
            }

            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
        }
Exemplo n.º 8
0
 /// <summary>
 /// Enables thread exit event for current thread.
 /// </summary>
 private static void EnableCurrentThreadExitEventMono(int callbackId, IntPtr threadLocalValue)
 {
     CheckResult(NativeMethodsMono.pthread_setspecific(callbackId, threadLocalValue));
 }
Exemplo n.º 9
0
 /// <summary>
 /// Removes thread exit callback that has been set with <see cref="SetThreadExitCallback"/>.
 /// </summary>
 private static void RemoveThreadExitCallbackMono(int callbackId)
 {
     CheckResult(NativeMethodsMono.pthread_key_delete(callbackId));
 }