Beispiel #1
0
 /// <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();
         }
     });
 }
Beispiel #2
0
    /// <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;
        }
    }