Fix memory leaks in Oracle Client. The largest leaks come from the cursors being...
authorNeale Ferguson <neale@sinenomine.net>
Thu, 10 Oct 2013 17:17:17 +0000 (13:17 -0400)
committerNeale Ferguson <neale@sinenomine.net>
Thu, 10 Oct 2013 17:17:17 +0000 (13:17 -0400)
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs

index 743a3c72ed81aaacc5c0dfb9c184e8092a48fcff..3e1ce93078593b520eef6e119a8529de49534402 100644 (file)
@@ -225,6 +225,11 @@ namespace System.Data.OracleClient.Oci
                                int xtramem_sz,
                                IntPtr usrmempp);
 
+                       [DllImport ("oci")]
+                       internal static extern int OCICacheFree (IntPtr envhp,
+                               IntPtr errhp,
+                               IntPtr stmthp);
+
                        [DllImport ("oci")]
                        internal static extern int OCIAttrGet (IntPtr trgthndlp,
                                [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
@@ -464,7 +469,7 @@ namespace System.Data.OracleClient.Oci
                                [MarshalAs (UnmanagedType.SysUInt)] int dstlen,
                                byte [] src,
                                [MarshalAs (UnmanagedType.SysUInt)] int srclen,
-                               [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
+                               out long rsize);
 
                        [DllImport ("oci")]
                        internal static extern int OCIUnicodeToCharSet (
@@ -473,7 +478,7 @@ namespace System.Data.OracleClient.Oci
                                [MarshalAs (UnmanagedType.SysUInt)] int dstlen,
                                [MarshalAs (UnmanagedType.LPWStr)] string src,
                                [MarshalAs (UnmanagedType.SysUInt)] int srclen,
-                               [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
+                               out long rsize);
                }
 
                #endregion
@@ -774,6 +779,16 @@ namespace System.Data.OracleClient.Oci
                                xtramem_sz, usrmempp);
                }
 
+               internal static int OCICacheFree (IntPtr envhp,
+                       IntPtr svchp,
+                       IntPtr stmthp)
+               {
+                       #if TRACE
+                       Trace.WriteLineIf(traceOci, "OCICacheFree", "OCI");
+                       #endif
+                       return OciNativeCalls.OCICacheFree (envhp, svchp, stmthp);
+               }
+
                internal static int OCIAttrGet (IntPtr trgthndlp,
                        OciHandleType trghndltyp,
                        out IntPtr attributep,
@@ -1185,24 +1200,37 @@ namespace System.Data.OracleClient.Oci
                        byte [] src,
                        out int rsize)
                {
+                       int rc;
+                       long retSize;
+
                        #if TRACE
                        Trace.WriteLineIf(traceOci, "OCICharSetToUnicode", "OCI");
                        #endif
-
-                       return OciNativeCalls.OCICharSetToUnicode (svchp, dst, dst!=null ? dst.Capacity : 0, src, src.Length, out rsize);
+                       rc = OciNativeCalls.OCICharSetToUnicode (svchp, dst,
+                                               (dst != null ? dst.Capacity : 0), 
+                                               src, src.Length, out retSize);
+                       rsize = (int) retSize;
+                       return(rc);
                }
 
                internal static int OCIUnicodeToCharSet (
                        IntPtr svchp,
                        byte [] dst,
-                       [MarshalAs (UnmanagedType.LPWStr)] string src,
-                       [MarshalAs (UnmanagedType.SysUInt)] out int rsize)
+                       string src,
+                       out int rsize)
                {
+                       int rc;
+                       long retSize;
+
                        #if TRACE
                        Trace.WriteLineIf(traceOci, "OCIUnicodeToCharSet", "OCI");
                        #endif
 
-                       return OciNativeCalls.OCIUnicodeToCharSet (svchp, dst, dst!=null ? dst.Length : 0, src, src.Length, out rsize);
+                       rc = OciNativeCalls.OCIUnicodeToCharSet (svchp, dst,
+                                       (dst != null ? dst.Length : 0), 
+                                       src, src.Length, out retSize);
+                       rsize = (int) retSize;
+                       return(rc);
                }
 
                [DllImport ("oci")]
index 31afb5cb3246e972c630e1a79980dc261064d5cf..8bbd545fa4be8cdcec7472e477d98cbbaff4b7ca 100644 (file)
@@ -32,6 +32,7 @@ namespace System.Data.OracleClient.Oci {
                bool moreResults;
                OciServiceHandle serviceHandle;
                ArrayList values;
+               ArrayList parm;
                OracleCommand command;
        
                #endregion // Fields
@@ -82,12 +83,11 @@ namespace System.Data.OracleClient.Oci {
                                
                                if (disposing) {
                                        if (values != null) {
-                                               foreach (OciDefineHandle h in values)
+                                               foreach (OciDefineHandle h in values) 
                                                        h.Dispose ();
                                                values = null;
                                        }
                                }
-                               
                                base.Dispose (disposing);
                        }
                }
@@ -110,6 +110,9 @@ namespace System.Data.OracleClient.Oci {
 
                        OciParameterDescriptor output = new OciParameterDescriptor (this, handle);
                        output.ErrorHandle = ErrorHandle;
+                       if (parm == null)
+                               parm = new ArrayList();
+                       parm.Add(handle);
                        return output;
                }
 
@@ -228,6 +231,8 @@ namespace System.Data.OracleClient.Oci {
                        switch (status) {
                        case OciGlue.OCI_NO_DATA:
                                moreResults = false;
+                               foreach (IntPtr h in parm)
+                                       OciCalls.OCIDescriptorFree(h, OciHandleType.Parameter);
                                break;
                        case OciGlue.OCI_DEFAULT:
                                moreResults = true;
index db39d3d551fe0ba6d4a1031cce61ca67fd66604e..8d05612c41728abbd63bbb5fe877ef746f947bed 100644 (file)
@@ -27,6 +27,7 @@ using System.Data.Common;
 using System.Data.OracleClient.Oci;
 using System.Drawing.Design;
 using System.Text;
+using System.Threading;
 
 namespace System.Data.OracleClient
 {
@@ -268,6 +269,7 @@ namespace System.Data.OracleClient
 
                private void BindParameters (OciStatementHandle statement)
                {
+Console.Error.WriteLine("{0} - BindParameter",Thread.CurrentThread.ManagedThreadId);
                        for (int p = 0; p < Parameters.Count; p++)
                                Parameters[p].Bind (statement, Connection, (uint) p);
                }
@@ -705,7 +707,7 @@ namespace System.Data.OracleClient
 
                private void SafeDisposeHandle (OciStatementHandle h)
                {
-                       if (h != null && h != preparedStatement)
+                       if (h != null && h != preparedStatement) 
                                h.Dispose();
                }
 
@@ -757,6 +759,9 @@ namespace System.Data.OracleClient
 
                protected override void Dispose (bool disposing)
                {
+                       if (preparedStatement != null) 
+                               OciCalls.OCIHandleFree(preparedStatement,
+                                                      OciHandleType.Statement);
                        if (disposing)
                                if (Parameters.Count > 0)
                                        foreach (OracleParameter parm in Parameters)
index df17716097dbae6007a10a25bcc7dea4e652ee27..6f11d970f0d46c04f10686f54d92b13fa113a130 100644 (file)
@@ -821,8 +821,11 @@ namespace System.Data.OracleClient
                                        if (direction == ParameterDirection.Output || 
                                                direction == ParameterDirection.InputOutput || 
                                                direction == ParameterDirection.ReturnValue) {
-
-                                               cursor = IntPtr.Zero;
+                                               if (cursor != IntPtr.Zero) {
+                                                       OciCalls.OCIHandleFree (cursor,
+                                                               OciHandleType.Statement);
+                                                       cursor = IntPtr.Zero;
+                                               }
                                                OciCalls.OCIHandleAlloc (connection.Environment,
                                                        out cursor,
                                                        OciHandleType.Statement,