/// <summary> /// Raises a signal. /// /// Signals in Yogi are intended to be used similarly to POSIX signals. They /// have to be raised explicitly by the user (e.g. when receiving an actual /// POSIX signal like SIGINT) via this function. A signal will be received by /// all signal sets containing that signal. /// /// The cleanup handler fn will be called once all signal handlers have been /// called. /// /// Note: The cleanup handler fn can get called either from within the /// RaiseSignal() function or from any context within the program. /// </summary> /// <param name="signal">The signal to raise.</param> /// <param name="fn">Function to call after all signal sets have been notified.</param> public static void RaiseSignal(Signals signal, [Optional] RaiseSignalFnDelegate fn) { RaiseSignal <object>(signal, null, (sigarg) => { if (fn != null) { fn(); } }); }
/// <summary> /// Raises a signal. /// /// Signals in Yogi are intended to be used similarly to POSIX signals. They /// have to be raised explicitly by the user (e.g. when receiving an actual /// POSIX signal like SIGINT) via this function. A signal will be received by /// all signal sets containing that signal. /// /// The sigarg parameter can be used to deliver user-defined data to the /// signal handlers. /// /// The cleanup handler fn will be called once all signal handlers have been /// called. Once fn has been called, the sigarg parameter is not used any more /// and can be cleaned up. /// /// Note: The cleanup handler fn can get called either from within the /// RaiseSignal() function or from any context within the program. /// </summary> /// <typeparam name="T">Type of the sigarg parameter.</typeparam> /// <param name="signal">The signal to raise.</param> /// <param name="sigarg">Object to pass to the signal sets.</param> /// <param name="fn">Function call after all signal sets have been notified.</param> public static void RaiseSignal <T>(Signals signal, T sigarg, [Optional] RaiseSignalFnDelegate <T> fn) where T : class { YogiCore.RaiseSignalFnDelegate wrapper = (sigargPtr, userarg) => { try { if (fn != null) { T obj = null; if (sigargPtr != IntPtr.Zero) { obj = (T)GCHandle.FromIntPtr(sigargPtr).Target; } fn(obj); } } finally { GCHandle.FromIntPtr(sigargPtr).Free(); GCHandle.FromIntPtr(userarg).Free(); } }; var wrapperHandle = GCHandle.Alloc(wrapper); var sigargHandle = GCHandle.Alloc(sigarg); try { var wrapperPtr = GCHandle.ToIntPtr(wrapperHandle); var sigargPtr = GCHandle.ToIntPtr(sigargHandle); int res = YogiCore.YOGI_RaiseSignal((int)signal, sigargPtr, wrapper, wrapperPtr); CheckErrorCode(res); } catch { sigargHandle.Free(); wrapperHandle.Free(); throw; } }