]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
P/Invoke should do all the work for us
authorMichael Giagnocavo <mgg@giagnocavo.net>
Thu, 2 Oct 2008 18:59:09 +0000 (18:59 +0000)
committerMichael Giagnocavo <mgg@giagnocavo.net>
Thu, 2 Oct 2008 18:59:09 +0000 (18:59 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9797 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/languages/mod_managed/freeswitch_managed.cpp
src/mod/languages/mod_managed/freeswitch_managed.h
src/mod/languages/mod_managed/managed/ManagedSession.cs
src/mod/languages/mod_managed/mod_managed.cpp

index 119fb3a728e417eb8ab9b34672995d2a41c2d063..fe9d4dd381b06845448b9e7cf42e35f8cd7e4b23 100644 (file)
@@ -74,9 +74,6 @@ ManagedSession::~ManagedSession()
                // Don't let any callbacks use this CoreSession anymore\r
                switch_channel_set_private(channel, "CoreSession", NULL);\r
        }\r
-       // Free delegates\r
-       hangupDelegateHandle.Free();\r
-       dtmfDelegateHandle.Free();\r
 }\r
 \r
 bool ManagedSession::begin_allow_threads() \r
@@ -91,22 +88,23 @@ bool ManagedSession::end_allow_threads()
 \r
 void ManagedSession::check_hangup_hook() \r
 {\r
-       if (!hangupDelegateHandle.IsAllocated) {\r
+       if (!hangupDelegate) {\r
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");\r
                return;\r
        }\r
-       ((HangupDelegate^)hangupDelegateHandle.Target)();\r
+       hangupDelegate();\r
 }\r
 \r
 switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype) \r
 {\r
-       if (!dtmfDelegateHandle.IsAllocated) {\r
+       if (!dtmfDelegate) {\r
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");\r
                return SWITCH_STATUS_FALSE;;\r
        }\r
-       char *result = ((InputDelegate^)dtmfDelegateHandle.Target)(input, itype);\r
+       char *result = dtmfDelegate(input, itype);\r
 \r
        switch_status_t status = process_callback_result(result);\r
+       Marshal::FreeHGlobal(IntPtr(result)); // I think this is right\r
        return status;\r
 }\r
 \r
index 97b6d02fde6c4989d25ef3739fea51567d6b1ac1..b5f64c8d5f29506d38458f69c718ce1426d1a272 100644 (file)
@@ -99,8 +99,8 @@ using namespace System;
 using namespace System::Reflection;\r
 using namespace System::Runtime::InteropServices;\r
 \r
-delegate void HangupDelegate(void);\r
-delegate char* InputDelegate(void* input, switch_input_type_t type);\r
+typedef void (*hangupFunction)(void);\r
+typedef char* (*inputFunction)(void*, switch_input_type_t);\r
 \r
 public ref class FreeSwitchManaged\r
 {\r
@@ -130,8 +130,9 @@ public:
        virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);\r
 \r
 #ifdef _MANAGED\r
-       GCHandle dtmfDelegateHandle; // GCHandle to the input delegate \r
-       GCHandle hangupDelegateHandle; // GCHandle to the hangup delegate\r
+       // P/Invoke function pointer to delegates\r
+       inputFunction dtmfDelegate; \r
+       hangupFunction hangupDelegate; \r
 #else\r
        guint32 dtmfDelegateHandle; // GCHandle to the input delegate \r
        guint32 hangupDelegateHandle; // GCHandle to the hangup delegate\r
index e381283b59205133b2c4f2d3d6f67e132d23217a..5561673aefc156d217f35e3c77beab4fed892e1b 100644 (file)
@@ -47,8 +47,16 @@ namespace FreeSWITCH.Native
         /// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary>\r
         public void Initialize()\r
         {\r
+            // P/Invoke generated function pointers stick around until the delegate is collected\r
+            // By sticking the delegates in fields, their lifetime won't be less than the session\r
+            // So we don't need to worry about GCHandles and all that....\r
+            // Info here: http://blogs.msdn.com/cbrumme/archive/2003/05/06/51385.aspx\r
+            this._inputCallbackRef = inputCallback;\r
+            this._hangupCallback = hangupCallback;\r
             InitManagedSession(ManagedSession.getCPtr(this).Handle, inputCallback, hangupCallback);\r
         }\r
+        DtmfCallback _inputCallbackRef;\r
+        Action _hangupCallback;\r
 \r
         /// <summary>Function to execute when this session hangs up.</summary>\r
         public Action HangupFunction { get; set; }\r
index cca9fe7248b433a121d40be20027df3ee55d816c..1f19e4a10542068df5c0f755f3e92a40465581b5 100644 (file)
@@ -452,8 +452,7 @@ struct dotnet_conf_t {
 // Sets up delegates (and anything else needed) on the ManagedSession object\r
 // Called from ManagedSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC\r
 // Exported method.\r
-\r
-SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfDelegate, void *hangupDelegate) \r
+SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, inputFunction dtmfDelegate, hangupFunction hangupDelegate) \r
 {\r
        switch_assert(session);\r
        if (!session) {\r
@@ -461,8 +460,8 @@ SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfD
        }\r
        session->setDTMFCallback(NULL, "");\r
        session->setHangupHook(NULL);\r
-       session->dtmfDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(dtmfDelegate), InputDelegate::typeid));\r
-       session->hangupDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(hangupDelegate), HangupDelegate::typeid));\r
+       session->dtmfDelegate = dtmfDelegate;\r
+       session->hangupDelegate = hangupDelegate;\r
 }\r
 \r
 switch_status_t loadModDotnetManaged() \r