[Mono-bugs] [Bug 69839][Min] New - Problem with CallContext class

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Tue, 23 Nov 2004 11:33:03 -0500 (EST)


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 sebastien.robitaille@croesus.com.

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

--- shadow/69839	2004-11-23 11:33:03.000000000 -0500
+++ shadow/69839.tmp.7440	2004-11-23 11:33:03.000000000 -0500
@@ -0,0 +1,124 @@
+Bug#: 69839
+Product: Mono: Class Libraries
+Version: 1.0
+OS: Red Hat 9.0
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Minor
+Component: CORLIB
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: sebastien.robitaille@croesus.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Problem with CallContext class
+
+Description of Problem:
+
+(mono-1.0.4)
+
+If I create a custom ChannelSink and add data in the CallContext from 
+this Sink, the data added is removed from the CallContext during the 
+execution of the remote method.
+
+On MS.NET, you can add data to the CallContext from a Sink and retrieve 
+this data from the body of a remote method without problem.
+
+I had a quick look at mono source code and I think that this problem may 
+be related to the way mono handles LogicalCallContexts. As I understand, 
+RemotingServices.InternalExecuteMessage temporarily replaces the 
+CallContext data by the LogicalCallContext object during the execution 
+instead of adding it to the actual content.
+
+
+Steps to reproduce the problem:
+1. Create a class implementing the IServerChannelSinkProvider interface  
+and create a class implementing the IServerChannelSink interface with the 
+following method:
+
+public ServerProcessing ProcessMessage(
+		IServerChannelSinkStack sinkStack, 
+		IMessage requestMsg, 
+		ITransportHeaders requestHeaders, 
+		Stream requestStream, 
+		out IMessage responseMsg, 
+		out ITransportHeaders responseHeaders, 
+		out Stream responseStream)
+{
+	CallContext.SetData("MyDataSlot", "MyData")
+
+	return nextSink.ProcessMessage(
+				sinkStack, 
+				requestMsg, 
+				requestHeaders, 
+				requestStream, 
+				out responseMsg, 
+				out responseHeaders, 
+				out responseStream);
+}
+
+
+2. Create a MarshalByRefObject with a method that retrieves the data from 
+the CallContext:
+
+public void MyMethod()
+{
+	object o = CallContext.GetData("MyDataSlot");
+	if(o == null)
+	{
+		System.Console.WriteLine("Object is null");
+	}
+	else
+	{
+		System.Console.WriteLine(o.ToString());
+	}
+}
+
+3. Expose this class using the remoting infrastructure and register a 
+channel with the custom channel sink.
+
+i.e.
+
+BinaryServerFormatterSinkProvider binaryFormatterProvider = new 
+BinaryServerFormatterSinkProvider();
+
+MyChannelSinkProvider myProvider = new MyChannelSinkProvider();
+binaryFormatterProvider.Next = myProvider;
+
+Hashtable channelProperties = new Hashtable();
+channelProperties["port"] = 9999;
+
+TcpServerChannel channel = new TcpServerChannel(channelProperties, 
+binaryFormatterProvider);
+ChannelServices.RegisterChannel(channel);
+
+RemotingConfiguration.RegisterWellKnownServiceType(
+	typeof(MyObject),						
+	"MyObject",
+	WellKnownObjectMode.Singleton);
+
+4. Call the method from another program.
+
+Actual Results:
+Object is null
+
+Expected Results:
+MyData
+
+How often does this happen? 
+Always
+
+Additional Information:
+A workaround for this problem is to use a thread NamedDataSlot instead of 
+the CallContext class:
+
+In the Custom Sink:
+LocalDataStoreSlot slot = Thread.GetNamedDataSlot("MyDataSlot);
+Thread.SetData(slot, "MyData");
+
+In the remote method:
+LocalDataStoreSlot slot = Thread.GetNamedDataSlot("MyDataSlot);
+object o = Thread.GetData(slot);