/// <summary> /// Set callback for log max size exceeded. /// Applies only to USER policy. /// </summary> /// <param name="callback"> /// The callback object to invoke whenever the log size is exceeded. /// </param> public static void setLogSizeCb(MamaLogFileCallback callback) { // Dispose the old callback wrapper if (m_logSizeCbWrapper != null) { ((IDisposable)m_logSizeCbWrapper).Dispose(); m_logSizeCbWrapper = null; } // Null is allowed to clear the callback if (callback == null) { // Call the native function with null MamaWrapper.CheckResultCode(NativeMethods.mama_setLogSizeCb(null)); } else { // Create a new callback wrapper m_logSizeCbWrapper = new MamaCallbackWrapper <MamaLogFileCallback, LogSizeCallbackDelegate>( callback, null, new LogSizeCallbackDelegate(onNativeLogSizeExceeded)); // Call the native function MamaWrapper.CheckResultCode(NativeMethods.mama_setLogSizeCb((LogSizeCallbackDelegate)m_logSizeCbWrapper.NativeDelegate)); } }
/// <summary> /// This function will store the supplied wrapper and return an object /// that can be passed into the native layer as a closure. /// This should then be passed to the RemoveWrapper function to access /// the object whenever the native callback is invoked. /// </summary> /// <param name="wrapper"> /// The wrapper object to store. /// </param> /// <returns> /// The handle that can be passed to the native layer. /// </returns> internal IntPtr StoreWrapper(MamaCallbackWrapper <TCallback, TDelegate> wrapper) { // Returns long ret = 0; // Acquire the mutex mStoreMutex.WaitOne(); try { // Get the next Id mNextId++; // This will become the handle ret = mNextId; // Add the wrapper to the store using the Id as the key mStore.Add(ret, wrapper); } finally { // Release the mutex mStoreMutex.ReleaseMutex(); } // Write a log if (MamaLogLevel.MAMA_LOG_LEVEL_FINEST == Mama.getLogLevel()) { // Write details of the object that has bee added string message = string.Format("MamaCallbackStore: Wrapper stored for key {0} for callback {1}.", ret, wrapper.Callback.ToString()); Mama.log(MamaLogLevel.MAMA_LOG_LEVEL_FINEST, message); // Write the number of items message = string.Format("MamaCallbackStore: Store now contains {0} items.", mStore.Count); Mama.log(MamaLogLevel.MAMA_LOG_LEVEL_FINEST, message); } /* Return the next Id as the handle. */ return(new IntPtr(ret)); }
/// <summary> /// This function will remove a wrapper object from the store and return it /// to the caller. This object should then be disposed by the caller. /// </summary> /// <param name="handle"> /// Handle returned from the StoreWrapper function. /// </param> /// <returns> /// The callback wrapper associated with the supplied handle. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if the corresponding wrapper is not in the store. /// </exception> internal MamaCallbackWrapper <TCallback, TDelegate> RemoveWrapper(IntPtr handle) { // Returns MamaCallbackWrapper <TCallback, TDelegate> ret = null; // The object handle is the key long key = handle.ToInt64(); // Acquire the mutex mStoreMutex.WaitOne(); try { // Get the wrapper from the store ret = mStore[key]; // Remove the object from the store mStore.Remove(key); } finally { // Release the mutex mStoreMutex.ReleaseMutex(); } // Write a log if (MamaLogLevel.MAMA_LOG_LEVEL_FINEST == Mama.getLogLevel()) { // Write details of the object that has been removed string message = string.Format("MamaCallbackStore: Wrapper removed for key {0} for callback {1}.", key, ret.Callback.ToString()); Mama.log(MamaLogLevel.MAMA_LOG_LEVEL_FINEST, message); // Write the number of items message = string.Format("MamaCallbackStore: Store now contains {0} items.", mStore.Count); Mama.log(MamaLogLevel.MAMA_LOG_LEVEL_FINEST, message); } return(ret); }
/// <summary> /// This handler is called whenever an asynchronous publisher send has completed. /// </summary> /// <param name="publisher"> /// Native reference to the publisher/ /// </param> /// <param name="msg"> /// Native message. /// </param> /// <param name="status"> /// Status returned. /// </param> /// <param name="closure"> /// The closure is a reference to the callback wrapper object used to keep the C# /// objects alive. /// </param> private void onSendComplete(IntPtr publisher, IntPtr msg, int status, IntPtr closure) { // Extract the wrapper object from the store using (MamaCallbackWrapper <MamaSendCompleteCallback, MamaThrottledSendCompleteDelegate> wrapper = mCallbackStore.RemoveWrapper(closure)) { if (mReusableMsg == null) { mReusableMsg = new MamaMsg(msg); } else { mReusableMsg.setNativeHandle(msg); } MamaSendCompleteCallback callback = (MamaSendCompleteCallback)wrapper.Callback; callback.onSendComplete(this, mReusableMsg, (MamaStatus.mamaStatus)status, wrapper.Closure); } }
/// <summary> /// Send a p2p message from the specified inbox using the throttle. /// The lifecycle of the message sent is controlled by the user of the API. The /// callback indicates when the API is no longer using the message and can be /// destroyed/reused by the application. /// </summary> /// <param name="inbox">The MamaInbox which will process any response to the sent message.</param> /// <param name="message">The MamaMsg to send.</param> /// <param name="callback">The callback which will be invoked when the message /// is sent from the throttle queue.</param> /// <param name="closure">User supplied data returned when the callback is invoked.</param> public void sendFromInboxWithThrottle( MamaInbox inbox, MamaMsg message, MamaSendCompleteCallback callback, object closure) { #if MAMA_WRAPPERS_CHECK_ARGUMENTS if (inbox == null) { throw new ArgumentNullException("inbox"); } if (message == null) { throw new ArgumentNullException("message"); } if (callback == null) { throw new ArgumentNullException("callback"); } EnsurePeerCreated(); #endif // MAMA_WRAPPERS_CHECK_ARGUMENTS // Create a new callback wrapper MamaCallbackWrapper <MamaSendCompleteCallback, MamaThrottledSendCompleteDelegate> wrapper = new MamaCallbackWrapper <MamaSendCompleteCallback, MamaThrottledSendCompleteDelegate>( callback, closure, new MamaThrottledSendCompleteDelegate(onSendComplete)); // Add this to the store IntPtr nativeClosure = mCallbackStore.StoreWrapper(wrapper); // Call the native function int code = NativeMethods.mamaPublisher_sendFromInboxWithThrottle( nativeHandle, inbox.NativeHandle, message.NativeHandle, (Wombat.MamaPublisher.MamaThrottledSendCompleteDelegate)wrapper.NativeDelegate, nativeClosure); try { CheckResultCode(code); } // If something goes wrong then remove the wrapper from the store catch { // Remove the wrapper mCallbackStore.RemoveWrapper(nativeClosure); // Dispose it ((IDisposable)wrapper).Dispose(); // Rethrow the exception throw; } // Ensure that the message passed will not delete its native peer message.SelfManageLifeTime(false); }