[Mono-bugs] [Bug 59624][Cri] New - Remoting over HTTP creates new thread for each request.

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Fri, 4 Jun 2004 23:20:32 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by ryoung@novell.com.

http://bugzilla.ximian.com/show_bug.cgi?id=59624

--- shadow/59624	2004-06-04 23:20:32.000000000 -0400
+++ shadow/59624.tmp.4250	2004-06-04 23:20:32.000000000 -0400
@@ -0,0 +1,407 @@
+Bug#: 59624
+Product: Mono: Runtime
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 001 One hour
+Priority: Critical
+Component: misc
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: ryoung@novell.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Remoting over HTTP creates new thread for each request.
+
+Please fill in this template when reporting a bug, unless you know what you
+are doing.
+Description of Problem:
+
+With the beta 2 release of Mono.  When remoting over an http channel every
+request causes a thread to be spun.  This is exposing a memory leak.  As
+you make request you will see memory gradualy grow until no memory is
+available.  If you run the server in memprof you will see a thread start
+before every request.  This is causing the iFolder memory leak.
+
+The following code will reproduce the problem.
+
+using System;
+
+using System.IO;
+
+using System.Diagnostics;
+
+using System.Runtime.Remoting.Messaging;
+
+using System.Collections;
+
+using System.Runtime.Remoting;
+
+using System.Runtime.Remoting.Channels;
+
+using System.Runtime.Remoting.Channels.Http;
+
+using System.Runtime.Remoting.Channels.Tcp;
+
+using System.Runtime.Remoting.Activation;
+
+
+
+namespace RemotingTest
+
+{
+
+	public class ChannelSetup
+
+	{
+
+		private const string channelName = "RTestChannel";
+
+		static public bool tcp = false;
+
+		//static public bool tcp = true;
+
+		
+
+		/// <summary>
+
+		/// Method to register a client channel.
+
+		/// </summary>
+
+		public static void RegisterClientChannel(string server)
+
+		{
+
+			Hashtable props = new Hashtable();
+
+			props["port"] = 8352; //serviceUri.Port;
+
+			props["name"] = channelName;
+
+			
+
+			BinaryClientFormatterSinkProvider
+
+				clientSink = new BinaryClientFormatterSinkProvider();
+
+
+
+			if (tcp)
+
+			{
+
+				ChannelServices.RegisterChannel(new TcpClientChannel(props, clientSink));
+
+			}
+
+			else
+
+			{
+
+				ChannelServices.RegisterChannel(new HttpClientChannel(props, clientSink));
+
+			}
+
+			//RemotingConfiguration.RegisterActivatedClientType(typeof(Factory),
+string.Format("Http://{0}:8352", server));
+
+			//RemotingConfiguration.RegisterWellKnownClientType(new
+WellKnownClientTypeEntry(typeof(Factory),
+string.Format("tcp://{0}:8352/RemotingTest", server)));
+
+		}
+
+
+
+		/// <summary>
+
+		/// Method to register the server channel.
+
+		/// </summary>
+
+		public static void RegisterService()
+
+		{
+
+			Hashtable props = new Hashtable();
+
+			props["port"] = 8352; //serviceUri.Port;
+
+			props["name"] = channelName;
+
+			
+
+			BinaryServerFormatterSinkProvider
+
+				serverSink = new BinaryServerFormatterSinkProvider();
+
+				
+
+#if !MONO
+
+			serverSink.TypeFilterLevel =
+
+				System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
+
+#endif
+
+			if (tcp)
+
+			{
+
+				ChannelServices.RegisterChannel(new TcpServerChannel(props, serverSink));
+
+			}
+
+			else
+
+			{
+
+				ChannelServices.RegisterChannel(new HttpServerChannel(props, serverSink));
+
+			}
+
+			//RemotingConfiguration.RegisterActivatedServiceType(typeof(Factory));
+
+			//RemotingConfiguration.RegisterWellKnownServiceType(new
+WellKnownServiceTypeEntry(typeof(Factory), "RemotingTest.rem",
+WellKnownObjectMode.Singleton));
+
+		}
+
+	}
+
+
+
+	class Class1
+
+	{
+
+		/// <summary>
+
+		/// The main entry point for the application.
+
+		/// </summary>
+
+		[STAThread]
+
+		static void Main(string[] args)
+
+		{
+
+			if (args.Length < 1)
+
+				Console.WriteLine("Usage: {0} [C(lient) ServerIP | S{erver)]",
+System.Reflection.Assembly.GetExecutingAssembly());
+
+
+
+			if (args[0].StartsWith("C"))
+
+			{
+
+				new Client(args[1]);
+
+			}
+
+			else if (args[0].StartsWith("S"))
+
+			{
+
+				ChannelSetup.RegisterService();
+
+				RemotingServices.Marshal(new Factory(), "RemotingTest.rem");
+
+				Console.WriteLine("Press Enter to exit.");
+
+				Console.ReadLine();
+
+			}
+
+		}
+
+	}
+
+
+
+	public class Client
+
+	{
+
+		public Client(string server)
+
+		{
+
+			ChannelSetup.RegisterClientChannel(server);
+
+			Console.WriteLine("Starting.");
+
+			Factory f;
+
+			if (ChannelSetup.tcp)
+
+			{
+
+				f = (Factory)Activator.GetObject(typeof(Factory),
+string.Format("tcp://{0}:8352/RemotingTest.rem", server));
+
+			}
+
+			else
+
+			{
+
+				f = (Factory)Activator.GetObject(typeof(Factory),
+string.Format("http://{0}:8352/RemotingTest.rem", server));
+
+			}
+
+			//Factory f = new Factory();
+
+			while (true)
+
+			{
+
+				Server s = f.GetServer();
+
+				byte[] data;
+
+				data = s.GetData();
+
+				Console.WriteLine("Got {0} bytes of data.", data.Length);
+
+				s.PutData(data);
+
+				Console.WriteLine("Put {0} bytes of data.", data.Length);
+
+			}
+
+		}
+
+	}
+
+
+
+	public class Server : MarshalByRefObject
+
+	{
+
+
+
+		byte[] data;
+
+		public Server()
+
+		{
+
+			data = new byte[128 * 1024];
+
+			for (int i = 0; i < data.Length ; i++)
+
+				data[i] = (byte)(i); // % Byte.MaxValue);
+
+		}
+
+
+
+		/// <summary>
+
+		/// This will be used as a singleton do not expire the object.
+
+		/// </summary>
+
+		/// <returns>null (Do not expire object).</returns>
+
+		public override Object InitializeLifetimeService()
+
+		{
+
+			return null;
+
+		}
+
+
+
+		public byte[] GetData()
+
+		{
+
+			Console.WriteLine("Getting {0} bytes of data.", data.Length);
+
+			return data;
+
+		}
+
+
+
+		public void PutData(byte[] data)
+
+		{
+
+			Console.WriteLine("Put {0} bytes of data.", data.Length);
+
+		}
+
+	}
+
+
+
+	public class Factory : MarshalByRefObject
+
+	{
+
+		/// <summary>
+
+		/// This will be used as a singleton do not expire the object.
+
+		/// </summary>
+
+		/// <returns>null (Do not expire object).</returns>
+
+		public override Object InitializeLifetimeService()
+
+		{
+
+			return null;
+
+		}
+
+
+
+		public Server GetServer()
+
+		{
+
+			return new Server();
+
+		}
+
+	}
+
+}
+
+
+
+
+Steps to reproduce the problem:
+1. Run the attached program as follows "memprof mono RemotingTestServer.exe S"
+2.The Run the client as follows "mono RemotingTestServer.exe C localhost"   
+3. Watch the threads come and go.
+4. If you rebuild the test over tcp this does not happen.
+
+Actual Results:
+
+
+Expected Results:
+
+
+How often does this happen? 
+
+Every time.
+
+
+Additional Information: