Hi, Attached a smaller testcase which exhibits the second kind of hang.
Zoltan On Sat, Feb 7, 2009 at 8:45 PM, Zoltan Varga <var...@gmail.com> wrote: > Hi People, > > So these tests are still hanging, especially on the net 1.1 profile. > > What seems to happen is this: > - HtttpClientTransportSink.AsyncProcessMessage () is called, which > starts an async web request. > - either no response is received from HttpWebRequest, ie. > AsyncProcessResponseCallback is never called. This happens often, > but not every time. > - or, AsyncProcessResponseCallback is called, which calls > request.EndGetResponse (ar); which throws an exception on the net > 1.1 profile, which is rethrown by this code: > if (httpResponse == null || > httpResponse.StatusCode != > HttpStatusCode.InternalServerError) { > throw; > } > > now this happens on a threadpool thread, so nobody handles the > exception, the thread is aborted, thus the client never receives > a response, so it hangs. > > To repro: > in System.Runtime.Remoting, run make check FIXTURE=Remoting.HttpAsyncCallTest > > Zoltan >
using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Collections; using System.Globalization; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Lifetime; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Channels.Http; using System.Runtime.InteropServices; public class Tests { public static void Main (String[] args) { var o = new BaseCallTest (); o.Run (); o.TestInterfaceProcessContextData (); } } public class BaseCallTest { IChannelSender chs; string[] remoteUris; CallsDomainServer server; int remoteDomId; public void Run() { remoteDomId = CreateServer (); } public void End () { ShutdownServer (); } public static AppDomain CreateDomain (string friendlyName) { // return AppDomain.CreateDomain (friendlyName); return AppDomain.CreateDomain (friendlyName, null, Directory.GetCurrentDirectory (), ".", false); } AppDomain domain; protected virtual int CreateServer () { ChannelManager cm = CreateChannelManager (); chs = cm.CreateClientChannel (); ChannelServices.RegisterChannel (chs); Console.WriteLine (this.GetType ()); domain = BaseCallTest.CreateDomain ("testdomain"); server = (CallsDomainServer) domain.CreateInstanceAndUnwrap(GetType().Assembly.FullName,"CallsDomainServer"); Console.WriteLine ("D"); remoteUris = server.Start (cm); Console.WriteLine ("D2"); return server.GetDomId (); } protected virtual void ShutdownServer () { if (server != null) { server.Stop (); if (chs != null) ChannelServices.UnregisterChannel (chs); } } public virtual ChannelManager CreateChannelManager () { return new HttpChannelManager (); } public void TestInterfaceProcessContextData () { for (int i = 0; i < 100; ++i) { CallContext.FreeNamedDataSlot ("clientData"); CallContext.FreeNamedDataSlot ("serverData"); CallContext.FreeNamedDataSlot ("mustNotPass"); ContextData cdata = new ContextData (); CallContext.FreeNamedDataSlot ("clientData"); CallContext.FreeNamedDataSlot ("serverData"); cdata = new ContextData (); cdata.data = "hi from client"; cdata.id = 1123; cdata.testStep = 2; CallContext.SetData ("clientData", cdata); string mdata; try { Console.WriteLine ("1"); var RemoteObject = (IRemoteObject) Activator.GetObject (typeof(IRemoteObject), remoteUris[2]); DelegateProcessContextData de = new DelegateProcessContextData (RemoteObject.ProcessContextData); IAsyncResult ar = de.BeginInvoke (null,null); BaseCallTest.DoWork (); de.EndInvoke (ar); } catch (Exception ex) { Console.WriteLine ("2"); if (ex.InnerException != null) ex = ex.InnerException; if (ex.Message != "exception from server") throw; } cdata = CallContext.GetData ("clientData") as ContextData; mdata = CallContext.GetData ("mustNotPass") as string; } } public static void DoWork () { for (int n=0; n<10; n++) Thread.Sleep (1); } } // // The server running in the remote domain // class CallsDomainServer: MarshalByRefObject { IChannelReceiver ch; public string[] Start(ChannelManager cm) { Console.WriteLine ("BOO!"); try { ch = cm.CreateServerChannel (); ChannelServices.RegisterChannel ((IChannel)ch); RemotingConfiguration.RegisterWellKnownServiceType (typeof (RemoteObject), "test1", WellKnownObjectMode.SingleCall); RemotingConfiguration.RegisterWellKnownServiceType (typeof (RemoteObject), "test2", WellKnownObjectMode.SingleCall); RemotingConfiguration.RegisterWellKnownServiceType (typeof (RemoteObject), "test3", WellKnownObjectMode.SingleCall); string[] uris = new string[3]; uris[0] = ch.GetUrlsForUri ("test1")[0]; uris[1] = ch.GetUrlsForUri ("test2")[0]; uris[2] = ch.GetUrlsForUri ("test3")[0]; return uris; } catch (Exception ex) { Console.WriteLine (ex.ToString()); throw; } } public void Stop () { if (ch != null) ChannelServices.UnregisterChannel (ch); } public int GetDomId () { return Thread.GetDomainID(); } } [Serializable] public class ContextData : ILogicalThreadAffinative { public string data; public int id; public int testStep; } [Serializable] public abstract class ChannelManager { public abstract IChannelSender CreateClientChannel (); public abstract IChannelReceiver CreateServerChannel (); } // // Test interface // public interface IRemoteObject { void ProcessContextData (); } public abstract class InterfaceSurrogate : IRemoteObject { public IRemoteObject RemoteObject; public abstract void ProcessContextData (); } // // Test abstract base class // public abstract class AbstractRemoteObject : MarshalByRefObject { public abstract void ProcessContextData (); } // // Test class // public class RemoteObject : AbstractRemoteObject, IRemoteObject { public override void ProcessContextData () { Console.WriteLine ("HIT!"); try { string mdata = CallContext.GetData ("mustNotPass") as string; if (mdata != null) throw new Exception ("mustNotPass is not null"); ContextData cdata = CallContext.GetData ("clientData") as ContextData; if (cdata == null) throw new Exception ("server: clientData is null"); if (cdata.data != "hi from client" || cdata.id != 1123) throw new Exception ("server: clientData is not valid"); if (cdata.testStep == 2) throw new Exception ("exception from server2"); if (cdata.testStep != 1) throw new Exception ("invalid test step"); cdata = new ContextData (); cdata.data = "hi from server"; cdata.id = 3211; CallContext.SetData ("serverData", cdata); } catch (Exception ex) { Console.WriteLine (ex); throw; } } } public delegate void DelegateProcessContextData (); [Serializable] public class HttpChannelManager : ChannelManager { public override IChannelSender CreateClientChannel () { Hashtable options = new Hashtable (); options ["timeout"] = 10000; // 10s return new HttpClientChannel (options, null); } public override IChannelReceiver CreateServerChannel () { return new HttpChannel (0); } }
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list