annotate Remoting/RemotingManager.cs @ 110:5e717aac4c1d

Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 07 Nov 2014 18:33:34 +0100
parents fc3eb8e49ea6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 ???using System;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.Collections.Generic;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.IO;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Reflection;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using System.Reflection.Emit;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 using System.Runtime.Remoting;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7 using System.Runtime.Remoting.Messaging;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 using System.Runtime.Remoting.Proxies;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 using System.Runtime.Serialization;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 using System.Threading;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 using UCIS.Util;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 using SysThreadPool = System.Threading.ThreadPool;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 //[assembly: InternalsVisibleToAttribute("UCIS.Remoting.Proxies")]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 namespace UCIS.Remoting {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 public class RemotingManager {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 Dictionary<UInt32, PendingRemoteCall> pendingCalls = new Dictionary<uint, PendingRemoteCall>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 Dictionary<Thread, UInt32> waitingCallThreads = new Dictionary<Thread, UInt32>();
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 14
diff changeset
20 public Boolean Closed { get; private set; }
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 IDictionary<String, Object> incomingCallContext = new Dictionary<String, Object>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 [ThreadStatic]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 static IDictionary<String, Object> currentCallContext;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 public event Action<String> OnDebugLog;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 public event Action<Exception> OnErrorLog;
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 14
diff changeset
28 public event Action<RemotingManager> OnClosed;
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 private void DebugLog(String text, params Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 if (OnDebugLog != null) OnDebugLog(String.Format(text, args));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 private void ErrorLog(Exception ex) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 if (OnErrorLog != null) OnErrorLog(ex);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 public Object LocalRoot { get; set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 public IDictionary<String, Object> CallContext { get { return incomingCallContext; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 public static IDictionary<String, Object> CurrentCallContext { get { return currentCallContext; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 public RemotingManager(PacketStream stream) : this(stream, null) { }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 public RemotingManager(PacketStream stream, Object localRoot) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 this.stream = stream;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 this.LocalRoot = localRoot;
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 14
diff changeset
46 this.Closed = false;
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 stream.BeginReadPacketFast(ReceiveCallback, null);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 #region I/O, multiplexing, encoding
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 PacketStream stream;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 public PacketStream Stream { get { return stream; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 int streamIndex = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 Dictionary<int, StreamChannel> streamChannels = new Dictionary<int, StreamChannel>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 class StreamChannel : QueuedPacketStream {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 public RemotingManager Manager { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 public int StreamID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 public StreamChannel OtherSide { get; set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 public StreamChannel(RemotingManager conn, int sid) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 this.Manager = conn;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 this.StreamID = sid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 internal void AddBuffer(Byte[] buffer, int offset, int count) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 if (Closed) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 base.AddReadBufferCopy(buffer, offset, count);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 public override bool CanRead { get { return !Closed; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 public override bool CanWrite { get { return !Closed; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 public override void Flush() { }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 public override void Write(byte[] buffer, int offset, int count) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 if (Closed) throw new ObjectDisposedException("BaseStream", "The connection has been closed");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 Manager.WriteStreamChannelPacket(StreamID ^ 0x4000, buffer, offset, count);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 public override void Close() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 StreamChannel other = OtherSide;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 MultiplexorClosed();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 if (other != null) other.CloseInternal();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 lock (Manager.streamChannels) Manager.streamChannels.Remove(StreamID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 public void CloseInternal() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 MultiplexorClosed();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 lock (Manager.streamChannels) Manager.streamChannels.Remove(StreamID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 internal void MultiplexorClosed() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 base.Close();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 OtherSide = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 private void ReceiveCallback(IAsyncResult ar) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 if (ar.CompletedSynchronously) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 SysThreadPool.QueueUserWorkItem(ReceiveCallbackA, ar);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
101 ReceiveCallbackB(ar);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 private void ReceiveCallbackA(Object state) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 ReceiveCallbackB((IAsyncResult)state);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 private void ReceiveCallbackB(IAsyncResult ar) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 try {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 ArraySegment<Byte> packet = stream.EndReadPacketFast(ar);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 Byte[] array = packet.Array;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 if (packet.Count < 2) throw new ArgumentOutOfRangeException("packet.Count", "Packet is too small");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 int offset = packet.Offset;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 int sid = (array[offset + 0] << 8) | (array[offset + 1] << 0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 if ((sid & 0x8000) != 0) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 StreamChannel substr;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 if (streamChannels.TryGetValue(sid, out substr)) substr.AddBuffer(array, offset + 2, packet.Count - 2);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 stream.BeginReadPacketFast(ReceiveCallback, null);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 if (sid == 0) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 Object obj;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 using (MemoryStream ms = new MemoryStream(packet.Array, packet.Offset + 2, packet.Count - 2, false)) obj = Deserialize(ms);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 ReceiveObject(obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 } catch (Exception ex) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 Closed = true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 stream.Close();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 ObjectReferencesByID.Clear();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 RemoteObjectReferences.Clear();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 lock (pendingCalls) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 foreach (PendingRemoteCall call in pendingCalls.Values) call.SetError(new InvalidOperationException("The connection has been closed"));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 pendingCalls.Clear();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 lock (streamChannels) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 foreach (StreamChannel s in streamChannels.Values) s.MultiplexorClosed();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 streamChannels.Clear();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 ErrorLog(ex);
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 14
diff changeset
140 if (OnClosed != null) OnClosed(this);
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 private void SendObject(Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 if (Closed) throw new ObjectDisposedException("RemotingManager", "The connection has been closed");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 using (MemoryStream ms = new MemoryStream()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 ms.WriteByte(0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 ms.WriteByte(0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 Serialize(ms, obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 lock (stream) ms.WriteTo(stream);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 private void WriteStreamChannelPacket(int sid, Byte[] buffer, int offset, int count) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 Byte[] store = new Byte[count + 2];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 store[0] = (Byte)(sid >> 8);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 store[1] = (Byte)(sid >> 0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 Buffer.BlockCopy(buffer, offset, store, 2, count);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 lock (stream) stream.Write(store, 0, store.Length);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 public PacketStream GetStreamPair(out PacketStream remote) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 StreamChannel stream;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 int sid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 lock (streamChannels) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 if (Closed) throw new ObjectDisposedException("BaseStream", "Reading from the base stream failed");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 while (true) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 sid = Interlocked.Increment(ref streamIndex);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 if ((sid & 0xc000) != 0) streamIndex = sid = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 sid |= 0x8000;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 if (!streamChannels.ContainsKey(sid)) break;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 stream = new StreamChannel(this, sid);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 streamChannels.Add(sid, stream);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 stream.OtherSide = (StreamChannel)SyncCall(new CreateStreamRequest() { StreamObject = stream, StreamID = sid | 0x4000 });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 remote = stream.OtherSide;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 return stream;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 #region Incoming call processing
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 private void ReceiveObject(Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 if (obj is ReferenceReleaseRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 ReferenceReleaseRequest req = (ReferenceReleaseRequest)obj;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 RemoteObjectReference objref = (RemoteObjectReference)ObjectReferencesByID[req.ObjectID];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 if (objref.Release(req.ReferenceCount) == 0) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 ObjectReferencesByID.Remove(objref.ID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 RemoteObjectReferences.Remove(objref);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 DebugLog("Release remoted object {0} with reference count {1}; {2} objects referenced", objref.ID, req.ReferenceCount, RemoteObjectReferences.Count);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
191 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
192 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
193 } else if (obj is SynchronousCall) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 SynchronousCall sc = (SynchronousCall)obj;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 if (sc.IsResult) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 PendingRemoteCall call;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 lock (pendingCalls) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 call = pendingCalls[sc.CallID];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 pendingCalls.Remove(call.ID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 call.SetResult(sc.Data);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 } else if (sc.HasPreviousCallID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 PendingRemoteCall call;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 lock (pendingCalls) call = pendingCalls[sc.PreviousCallID];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205 if (!call.SetNextCall(sc)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 ProcessRemoteCallRequest(sc);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 ProcessRemoteCallRequest(sc);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 throw new InvalidDataException("Unexpected object type");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 private void ProcessRemoteCallRequest(SynchronousCall call) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 UInt32 prevcallid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 Boolean hasprevcallid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 Thread currentThread = Thread.CurrentThread;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 lock (waitingCallThreads) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 hasprevcallid = waitingCallThreads.TryGetValue(currentThread, out prevcallid);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
222 waitingCallThreads[currentThread] = call.CallID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
223 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
224 IDictionary<String, Object> prevCallContext = currentCallContext;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
225 currentCallContext = incomingCallContext;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
226 try {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 call.Data = ProcessRemoteCallRequestA(call.Data);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 } finally {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 currentCallContext = prevCallContext;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
230 lock (waitingCallThreads) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
231 if (hasprevcallid) waitingCallThreads[currentThread] = prevcallid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
232 else waitingCallThreads.Remove(currentThread);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
233 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
234 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
235 call.IsResult = true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
236 SendObject(call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
237 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
238
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
239 private Object FixReturnType(Object value, Type expectedType) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
240 if (value == null) return value;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
241 Type valueType = value.GetType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
242 if (valueType != expectedType) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
243 if (valueType.IsArray) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
244 Array retarray = value as Array;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
245 if (retarray != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
246 if (!valueType.GetElementType().IsPublic && retarray.Rank == 1 &&
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
247 (
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
248 expectedType.IsArray ||
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 (expectedType.IsGenericType && (expectedType.GetGenericTypeDefinition() == typeof(IEnumerable<>) || expectedType.GetGenericTypeDefinition() == typeof(ICollection<>) || expectedType.GetGenericTypeDefinition() == typeof(IList<>)))
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
250 )
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
251 ) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
252 Type btype = expectedType.IsArray ? expectedType.GetElementType() : expectedType.GetGenericArguments()[0];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
253 Array r = Array.CreateInstance(btype, retarray.Length);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
254 retarray.CopyTo(r, 0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
255 value = r;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
256 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
257 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
258 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
259 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
260 return value;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
262 private Object ProcessRemoteMethodCallRequestA(Object ret) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
263 if (ret is DelegateCallRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
264 DelegateCallRequest call = (DelegateCallRequest)ret;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
265 Object target = call.Delegate;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
266 DebugLog("Remote delegate call on {0}", target);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
267 if (ReferenceEquals(target, null)) throw new NullReferenceException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
268 if (!(target is Delegate)) throw new InvalidCastException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
269 Object[] args = call.Arguments;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
270 return ((Delegate)target).DynamicInvoke(args);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
271 } else if (ret is MethodCallRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
272 MethodCallRequest call = (MethodCallRequest)ret;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
273 Object target = call.Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
274 if (ReferenceEquals(target, null)) throw new NullReferenceException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
275 Type intf = call.Type ?? target.GetType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
276 DebugLog("Remote call {0}.{1} on {2}", intf.FullName, call.MethodName, target);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
277 if (!intf.IsInstanceOfType(target)) throw new InvalidCastException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
278 MethodInfo meth;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
279 if (call.MethodSignature != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
280 meth = intf.GetMethod(call.MethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, call.MethodSignature, null);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
281 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
282 meth = intf.GetMethod(call.MethodName, BindingFlags.Instance | BindingFlags.Public);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
283 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
284 if (meth == null) throw new NullReferenceException("method");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
285 Object[] args = call.Arguments;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
286 Object retval;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
287 if (meth.Name == "GetType" && meth == typeof(Object).GetMethod("GetType", Type.EmptyTypes)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
288 if (target.GetType().IsPublic) retval = target.GetType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
289 else retval = intf;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
290 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
291 retval = meth.Invoke(target, args);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
292 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
293 //Todo: causes lots of redundant data transfers, do something about it!
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
294 /*Object[] rargs = new Object[0];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
295 for (int i = 0; i < args.Length; i++) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
296 if (args[i] == null) continue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
297 if (args[i].GetType().IsArray) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
298 Array.Resize(ref rargs, i + 1);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
299 rargs[i] = args[i];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
300 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
301 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
302 resp.ReturnArguments = rargs;*/
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
303 return FixReturnType(retval, meth.ReturnType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
304 } else if (ret is PropertyAccessRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
305 PropertyAccessRequest call = (PropertyAccessRequest)ret;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
306 Object target = call.Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
307 if (ReferenceEquals(target, null)) throw new NullReferenceException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
308 Type intf = call.Type ?? target.GetType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
309 DebugLog("Remote property access {0}.{1} on {2}", intf.FullName, call.PropertyName, target);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
310 if (!intf.IsInstanceOfType(target)) throw new InvalidCastException("target");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
311 PropertyInfo meth = intf.GetProperty(call.PropertyName, BindingFlags.Instance | BindingFlags.Public);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
312 if (meth == null) throw new NullReferenceException("property");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
313 if (call.SetValue) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
314 meth.SetValue(target, call.Value, null);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
315 return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
316 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
317 return FixReturnType(meth.GetValue(target, null), meth.PropertyType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
318 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
319 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
320 throw new InvalidDataException("Unexpected object type");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
321 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
322 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
323 private Object ProcessRemoteCallRequestA(Object ret) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
324 if (ret is DelegateCallRequest || ret is MethodCallRequest || ret is PropertyAccessRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
325 MethodCallResponse resp = new MethodCallResponse();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
326 try {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
327 resp.ReturnValue = ProcessRemoteMethodCallRequestA(ret);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
328 } catch (Exception ex) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
329 resp.Exception = ex;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
330 ErrorLog(ex);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
331 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
332 return resp;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
333 } else if (ret is GetRootRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
334 DebugLog("Remote root request");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
335 return LocalRoot;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
336 } else if (ret is ObjectCanCastToRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
337 ObjectCanCastToRequest ctr = (ObjectCanCastToRequest)ret;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
338 Type intf = ctr.Type;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
339 Object target = ctr.Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
340 DebugLog("Remote type check for {0} on {1}", intf.Name, target);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
341 return intf != null && intf.IsInstanceOfType(target);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
342 } else if (ret is CreateStreamRequest) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
343 CreateStreamRequest csr = (CreateStreamRequest)ret;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
344 StreamChannel ss = new StreamChannel(this, csr.StreamID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
345 ss.OtherSide = csr.StreamObject;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
346 lock (streamChannels) streamChannels.Add(csr.StreamID, ss);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
347 return ss;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
348 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
349 throw new InvalidDataException("Unexpected object type");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
350 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
351 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
352 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
353
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
354 #region Outgoing calls
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
355 UInt32 callID = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
356 private UInt32 AllocatePendingCallID(PendingRemoteCall call) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
357 UInt32 cid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
358 lock (pendingCalls) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
359 while (true) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
360 cid = ++callID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
361 if (!pendingCalls.ContainsKey(cid)) break;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
362 Monitor.Wait(pendingCalls);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
363 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
364 call.ID = cid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
365 pendingCalls.Add(cid, call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
366 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
367 return cid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
368 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
369 private Object SyncCall(Object req) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
370 UInt32 previousCall;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
371 Boolean hasPreviousCall;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
372 lock (waitingCallThreads) hasPreviousCall = waitingCallThreads.TryGetValue(Thread.CurrentThread, out previousCall);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
373 PendingRemoteCall pending = new PendingRemoteCall() { Completed = false, WaitHandle = new ManualResetEvent(false), CallData = req };
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
374 AllocatePendingCallID(pending);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
375 SynchronousCall call = new SynchronousCall() { IsResult = false, CallID = pending.ID, Data = req, HasPreviousCallID = false };
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
376 if (hasPreviousCall) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
377 call.HasPreviousCallID = true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
378 call.PreviousCallID = previousCall;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
379 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
380 SendObject(call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
381 while (true) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
382 pending.WaitHandle.WaitOne();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
383 if (pending.Completed) break;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
384 pending.WaitHandle.Reset();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
385 if (pending.NextCall == null) throw new InvalidOperationException("Operation did not complete");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
386 SynchronousCall sc = pending.NextCall.Value;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
387 pending.NextCall = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
388 ProcessRemoteCallRequest(sc);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
389 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
390 pending.WaitHandle.Close();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
391 if (pending.Error != null) throw pending.Error;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
392 return pending.Response;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
393 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
394 private void AsyncCall(Object req) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
395 UInt32 cid = AllocatePendingCallID(new PendingRemoteCall() { Completed = false, CallData = req });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
396 SendObject(new SynchronousCall() { IsResult = false, CallID = cid, Data = req, HasPreviousCallID = false });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
397 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
398
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
399 public Object RemoteRoot {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
400 get {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
401 return SyncCall(new GetRootRequest());
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
402 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
403 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
404
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
405 public static void AsyncCall(Delegate f, params Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
406 IProxyBase proxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
407 if ((proxy = GetRealProxyForObject(f)) != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
408 proxy.Manager.AsyncCall(new DelegateCallRequest() { Delegate = proxy, Arguments = args });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
409 } else if ((proxy = GetRealProxyForObject(f.Target)) != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
410 MethodCallRequest call = new MethodCallRequest() { Object = proxy, Type = f.Method.DeclaringType, MethodName = f.Method.Name, Arguments = args };
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
411 call.MethodSignature = ConvertMethodParameterTypeArray(f.Method);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
412 proxy.Manager.AsyncCall(call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
413 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
414 throw new InvalidOperationException("Delegate is not a proxy for a remote object");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
415 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
416 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
417
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
418 private static Type[] ConvertMethodParameterTypeArray(MethodInfo method) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
419 ParameterInfo[] parameters = method.GetParameters();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
420 Type[] types = new Type[parameters.Length];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
421 for (int i = 0; i < types.Length; i++) types[i] = parameters[i].ParameterType;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
422 return types;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
423 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
424 private void ProxyCallCheckReturnType(Object value, Type type) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
425 if (type == typeof(void)) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
426 if (type.IsInstanceOfType(value)) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
427 if (value == null && !type.IsValueType) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
428 throw new InvalidCastException("Type returned by remote procedure does not match expected type.");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
429 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
430 private void ProxyCallFixReturnArguments(Object[] args, Object[] rargs) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
431 if (rargs == null) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
432 for (int i = 0; i < rargs.Length; i++) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
433 if (rargs[i] == null) continue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
434 if (args[i] != null && args[i].GetType().IsArray) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
435 ((Array)rargs[i]).CopyTo((Array)args[i], 0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
436 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
437 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
438 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
439 private Object ProxyMakeCallDelegate(DelegateProxy obj, Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
440 DelegateCallRequest call = new DelegateCallRequest() { Delegate = obj, Arguments = args };
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
441 MethodCallResponse resp = (MethodCallResponse)SyncCall(call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
442 if (resp.Exception != null) throw new Exception("Remote exception", resp.Exception);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
443 ProxyCallFixReturnArguments(args, resp.ReturnArguments);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
444 ProxyCallCheckReturnType(resp.ReturnValue, obj.MethodSignature.ReturnType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
445 return resp.ReturnValue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
446 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
447 private Object ProxyMakeCall(IProxyBase obj, MethodInfo method, Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
448 /*if (args.Length == 1 && method.ReturnType == typeof(void) && args[0] != null && args[0] is Delegate) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
449 foreach (EventInfo ei in type.GetEvents()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
450 if (ei.EventHandlerType.IsInstanceOfType(args[0])) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
451 if (method == ei.GetAddMethod()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
452 Console.WriteLine("ADD EVENT");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
453 } else if (method == ei.GetRemoveMethod()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
454 Console.WriteLine("REMOVE EVENT");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
455 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
456 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
457 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
458 }*/
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
459 MethodCallRequest call = new MethodCallRequest() { Object = obj, Type = method.DeclaringType, MethodName = method.Name, Arguments = args };
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
460 call.MethodSignature = ConvertMethodParameterTypeArray(method);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
461 MethodCallResponse resp = (MethodCallResponse)SyncCall(call);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
462 if (resp.Exception != null) throw new Exception("Remote exception", resp.Exception);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
463 ProxyCallFixReturnArguments(args, resp.ReturnArguments);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
464 ProxyCallCheckReturnType(resp.ReturnValue, method.ReturnType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
465 return resp.ReturnValue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
466 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
467 private Boolean ProxyCanCastTo(IProxyBase obj, Type type) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
468 return (Boolean)SyncCall(new ObjectCanCastToRequest() { Object = obj, Type = type });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
469 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
470 private void ProxyReleaseObject(ProxyObjectReference objref) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
471 if (objref == null) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
472 ProxyReleaseObject(objref, objref.RefCnt);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
473 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
474 private void ProxyReleaseObject(ProxyObjectReference objref, int refcnt) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
475 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
476 int newrefcnt = objref.Release(refcnt);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
477 IObjectReferenceBase regobjref;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
478 if (newrefcnt <= 0 && ObjectReferencesByID.TryGetValue(objref.ID, out regobjref) && objref == regobjref) ObjectReferencesByID.Remove(objref.ID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
479 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
480 try {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
481 if (Closed) return;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
482 SendObject(new ReferenceReleaseRequest() { ObjectID = objref.RemoteID, ReferenceCount = refcnt });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
483 } catch (Exception) { } //Assume the exception happened because the connection is closed. Otherwise memory leak...
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
484 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
485
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
486 class PendingRemoteCall {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
487 public UInt32 ID = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
488 public ManualResetEvent WaitHandle = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
489 public Object Response = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
490 public Exception Error = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
491 public Boolean Completed = false;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
492 public SynchronousCall? NextCall = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
493 public Object CallData = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
494
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
495 public void SetError(Exception error) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
496 this.Error = error;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
497 Completed = true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
498 if (WaitHandle != null) WaitHandle.Set();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
499 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
500 public void SetResult(Object result) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
501 this.Response = result;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
502 Completed = true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
503 if (WaitHandle != null) WaitHandle.Set();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
504 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
505 public Boolean SetNextCall(SynchronousCall nextcall) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
506 if (WaitHandle == null) return false;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
507 this.NextCall = nextcall;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
508 WaitHandle.Set();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
509 return true;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
510 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
511 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
512 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
513
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
514 #region Object serialization support
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
515 private void Serialize(Stream stream, Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
516 BinaryWriter writer = new BinaryWriter(stream);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
517 Serialize(writer, obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
518 writer.Flush();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
519 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
520 private void Serialize(BinaryWriter writer, Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
521 if (ReferenceEquals(obj, null)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
522 writer.Write((Byte)0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
523 } else if (GetRealProxyForObject(obj) != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
524 GetObjectData(obj, writer);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
525 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
526 Type type = obj.GetType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
527 if (type == typeof(Boolean)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
528 writer.Write((Byte)1);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
529 writer.Write((Boolean)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
530 } else if (type == typeof(Byte)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
531 writer.Write((Byte)2);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
532 writer.Write((Byte)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
533 } else if (type == typeof(Char)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
534 writer.Write((Byte)3);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
535 writer.Write((Int16)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
536 } else if (type == typeof(Decimal)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
537 writer.Write((Byte)4);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
538 writer.Write((Decimal)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
539 } else if (type == typeof(Double)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
540 writer.Write((Byte)5);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
541 writer.Write((Double)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
542 } else if (type == typeof(Int16)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
543 writer.Write((Byte)6);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
544 writer.Write((Int16)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
545 } else if (type == typeof(Int32)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
546 writer.Write((Byte)7);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
547 writer.Write((Int32)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
548 } else if (type == typeof(Int64)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
549 writer.Write((Byte)8);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
550 writer.Write((Int64)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
551 } else if (type == typeof(SByte)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
552 writer.Write((Byte)9);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
553 writer.Write((SByte)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
554 } else if (type == typeof(Single)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
555 writer.Write((Byte)10);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
556 writer.Write((Single)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
557 } else if (type == typeof(String)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
558 writer.Write((Byte)11);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
559 writer.Write((String)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
560 } else if (type == typeof(UInt16)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
561 writer.Write((Byte)12);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
562 writer.Write((UInt16)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
563 } else if (type == typeof(UInt32)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
564 writer.Write((Byte)13);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
565 writer.Write((UInt32)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
566 } else if (type == typeof(UInt64)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
567 writer.Write((Byte)14);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
568 writer.Write((UInt64)obj);
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
569 } else if (type == typeof(DateTime)) {
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
570 writer.Write((Byte)32);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
571 writer.Write((Int64)((DateTime)obj).ToBinary());
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
572 } else if (type.IsSubclassOf(typeof(Type))) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
573 writer.Write((Byte)165);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
574 SerializeType(writer, (Type)obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
575 } else if (type.IsArray) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
576 writer.Write((Byte)164);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
577 Array arr = (Array)obj;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
578 writer.Write((int)arr.Length);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
579 SerializeType(writer, type.GetElementType());
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
580 for (int i = 0; i < arr.Length; i++) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
581 Serialize(writer, arr.GetValue(i));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
582 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
583 } else if (type.IsPrimitive) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
584 throw new NotSupportedException();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
585 } else if (typeof(Delegate).IsAssignableFrom(type) || type.IsMarshalByRef) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
586 GetObjectData(obj, writer);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
587 } else if (obj is ISerializable) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
588 SerializationInfo si = new SerializationInfo(type, new FormatterConverter());
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
589 ((ISerializable)obj).GetObjectData(si, new StreamingContext(StreamingContextStates.All));
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
590 writer.Write((Byte)128);
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
591 SerializeType(writer, Type.GetType(si.FullTypeName + "," + si.AssemblyName));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
592 writer.Write((int)si.MemberCount);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
593 foreach (SerializationEntry se in si) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
594 writer.Write(se.Name);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
595 Serialize(writer, se.Value);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
596 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
597 } else if (type.IsSerializable) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
598 MemberInfo[] members = FormatterServices.GetSerializableMembers(type);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
599 Object[] values = FormatterServices.GetObjectData(obj, members);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
600 writer.Write((Byte)128);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
601 SerializeType(writer, type);
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
602 writer.Write((int)members.Length);
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
603 for (int i = 0; i < members.Length; i++) {
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
604 writer.Write(members[i].Name);
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
605 Serialize(writer, values[i]);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
606 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
607 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
608 GetObjectData(obj, writer);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
609 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
610 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
611 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
612 private void SerializeType(BinaryWriter writer, Type t) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
613 writer.Write(t.FullName);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
614 writer.Write(t.Assembly.FullName);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
615 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
616 private Object Deserialize(Stream stream) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
617 BinaryReader reader = new BinaryReader(stream);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
618 return Deserialize(reader);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
619 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
620 private Object Deserialize(BinaryReader reader) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
621 Byte t = reader.ReadByte();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
622 if (t == 0) return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
623 if (t == 1) return reader.ReadBoolean();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
624 if (t == 2) return reader.ReadByte();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
625 if (t == 3) return (Char)reader.ReadInt16();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
626 if (t == 4) return reader.ReadDecimal();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
627 if (t == 5) return reader.ReadDouble();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
628 if (t == 6) return reader.ReadInt16();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
629 if (t == 7) return reader.ReadInt32();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
630 if (t == 8) return reader.ReadInt64();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
631 if (t == 9) return reader.ReadSByte();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
632 if (t == 10) return reader.ReadSingle();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
633 if (t == 11) return reader.ReadString();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
634 if (t == 12) return reader.ReadUInt16();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
635 if (t == 13) return reader.ReadUInt32();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
636 if (t == 14) return reader.ReadUInt64();
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
637 if (t == 32) return DateTime.FromBinary(reader.ReadInt64());
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
638 if (t == 128) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
639 Type type = DeserializeType(reader);
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
640 int cnt = reader.ReadInt32();
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
641 Object inst;
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
642 StreamingContext sc = new StreamingContext(StreamingContextStates.All);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
643 if (typeof(ISerializable).IsAssignableFrom(type) && type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null) != null) {
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
644 SerializationInfo si = new SerializationInfo(type, new FormatterConverter());
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
645 for (int i = 0; i < cnt; i++) {
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
646 String name = reader.ReadString();
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
647 Object value = Deserialize(reader);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
648 si.AddValue(name, value);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
649 }
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
650 inst = Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Object[] { si, sc }, null);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
651 } else if (type.IsSerializable) {
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
652 inst = FormatterServices.GetUninitializedObject(type);
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
653 List<MemberInfo> members = new List<MemberInfo>();
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
654 List<Object> values = new List<object>();
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
655 for (int i = 0; i < cnt; i++) {
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
656 String mname = reader.ReadString();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
657 Object value = Deserialize(reader);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
658 MemberInfo[] mms = type.GetMember(mname, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
659 if (mms.Length != 1) throw new InvalidOperationException();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
660 members.Add(mms[0]);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
661 values.Add(value);
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
662 }
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
663 FormatterServices.PopulateObjectMembers(inst, members.ToArray(), values.ToArray());
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
664 } else {
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
665 throw new InvalidOperationException("Type " + type.Name + " is not serializable");
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
666 }
14
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
667 IObjectReference objref = inst as IObjectReference;
fc3eb8e49ea6 Remoting: fixes for linux/mono
Ivo Smits <Ivo@UCIS.nl>
parents: 13
diff changeset
668 if (objref != null) inst = objref.GetRealObject(sc);
13
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
669 return inst;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
670 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
671 if (t == 129 || t == 130 || t == 131) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
672 return SetObjectData(t, reader);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
673 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
674 if (t == 164) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
675 int len = reader.ReadInt32();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
676 Type type = DeserializeType(reader); Array arr = Array.CreateInstance(type, len);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
677 for (int i = 0; i < len; i++) arr.SetValue(Deserialize(reader), i);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
678 return arr;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
679 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
680 if (t == 165) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
681 return DeserializeType(reader);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
682 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
683 throw new NotSupportedException();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
684 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
685 private Type DeserializeType(BinaryReader reader) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
686 String name = reader.ReadString();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
687 String aname = reader.ReadString();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
688 Type t = Type.GetType(name + ", " + aname, false);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
689 if (t != null) return t;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
690 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
691 t = assembly.GetType(name, false);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
692 if (t != null) return t;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
693 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
694 return t;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
695 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
696
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
697 Dictionary<UInt32, IObjectReferenceBase> ObjectReferencesByID = new Dictionary<uint, IObjectReferenceBase>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
698 List<RemoteObjectReference> RemoteObjectReferences = new List<RemoteObjectReference>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
699 uint remoteReferenceIndex = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
700 void GetObjectData(object obj, BinaryWriter w) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
701 IObjectReferenceBase rref = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
702 IProxyBase proxy = GetRealProxyForObject(obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
703 if (proxy != null && proxy.Manager == this) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
704 rref = proxy.ObjectReference;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
705 w.Write((Byte)131);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
706 w.Write((UInt32)rref.RemoteID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
707 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
708 Boolean isDelegate = obj is Delegate;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
709 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
710 foreach (IObjectReferenceBase objref in RemoteObjectReferences) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
711 Object other = objref.Target;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
712 if (ReferenceEquals(other, obj) || (isDelegate && Delegate.Equals(other, obj))) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
713 rref = objref;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
714 break;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
715 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
716 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
717 if (rref == null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
718 UInt32 objid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
719 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
720 while (true) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
721 remoteReferenceIndex++;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
722 objid = remoteReferenceIndex;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
723 if ((objid & 0x80000000) != 0) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
724 remoteReferenceIndex = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
725 continue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
726 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
727 if (!ObjectReferencesByID.ContainsKey(objid)) break;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
728 Monitor.Wait(ObjectReferencesByID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
729 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
730 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
731 rref = new RemoteObjectReference(objid, obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
732 ObjectReferencesByID.Add(objid, rref);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
733 RemoteObjectReferences.Add((RemoteObjectReference)rref);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
734 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
735 rref.AddRef();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
736 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
737 if (isDelegate) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
738 w.Write((Byte)130);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
739 w.Write((UInt32)rref.RemoteID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
740 SerializeType(w, obj.GetType());
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
741 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
742 w.Write((Byte)129);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
743 w.Write((UInt32)rref.RemoteID);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
744 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
745 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
746 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
747 object SetObjectData(Byte t, BinaryReader r) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
748 UInt32 objid = r.ReadUInt32();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
749 Type deltype = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
750 if (t == 130) deltype = DeserializeType(r);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
751 lock (ObjectReferencesByID) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
752 Object target = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
753 IObjectReferenceBase rref;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
754 if (ObjectReferencesByID.TryGetValue(objid, out rref)) target = rref.Target;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
755 if (t == 131) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
756 if (target == null) throw new InvalidOperationException("Object not found");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
757 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
758 if (target == null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
759 if ((objid & 0x80000000) == 0) throw new InvalidOperationException("The Object ID is invalid");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
760 IProxyBase proxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
761 if (t == 130) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
762 proxy = CreateDelegateProxy(objid, deltype);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
763 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
764 String[] iftypes = null; //(String[])info.GetValue("InterfaceTypes", typeof(String[]));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
765 proxy = CreateObjectProxy(objid, iftypes);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
766 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
767 rref = proxy.ObjectReference;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
768 ObjectReferencesByID[objid] = rref;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
769 target = proxy.GetTransparentProxy();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
770 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
771 rref.AddRef();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
772 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
773 return target;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
774 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
775 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
776 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
777
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
778 #region RPC messages
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
779 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
780 struct SynchronousCall {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
781 public UInt32 CallID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
782 public Boolean IsResult;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
783 public Object Data;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
784 public Boolean HasPreviousCallID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
785 public UInt32 PreviousCallID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
786 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
787
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
788 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
789 struct MethodCallRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
790 public Object Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
791 public Type Type;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
792 public String MethodName;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
793 public Type[] MethodSignature;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
794 public Object[] Arguments;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
795 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
796 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
797 struct MethodCallResponse {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
798 public Exception Exception;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
799 public Object ReturnValue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
800 public Object[] ReturnArguments;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
801 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
802 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
803 struct PropertyAccessRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
804 public Object Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
805 public Type Type;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
806 public String PropertyName;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
807 public Boolean SetValue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
808 public Object Value;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
809 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
810 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
811 struct ReferenceReleaseRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
812 public UInt32 ObjectID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
813 public Int32 ReferenceCount;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
814 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
815 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
816 struct GetRootRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
817 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
818 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
819 struct ObjectCanCastToRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
820 public Object Object;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
821 public Type Type;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
822 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
823 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
824 struct CreateStreamRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
825 public StreamChannel StreamObject;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
826 public int StreamID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
827 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
828 [Serializable]
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
829 struct DelegateCallRequest {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
830 public Object Delegate;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
831 public Object[] Arguments;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
832 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
833 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
834
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
835 #region Proxy magic
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
836 static IProxyBase GetRealProxyForObject(Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
837 if (RemotingServices.IsTransparentProxy(obj)) return RemotingServices.GetRealProxy(obj) as FWProxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
838 IProxyBase obj_IProxyBase = obj as IProxyBase;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
839 if (obj_IProxyBase != null) return obj_IProxyBase;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
840 Delegate obj_Delegate = obj as Delegate;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
841 if (obj_Delegate != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
842 DelegateProxy pb = obj_Delegate.Target as DelegateProxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
843 if (pb != null) return pb;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
844 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
845 return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
846 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
847 public static RemotingManager GetManagerForObjectProxy(Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
848 IProxyBase prox = GetRealProxyForObject(obj);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
849 if (prox == null) return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
850 return prox.Manager;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
851 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
852
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
853 interface IObjectReferenceBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
854 UInt32 ID { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
855 Object Target { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
856 int AddRef();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
857 int RefCnt { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
858 Boolean IsLocal { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
859 UInt32 RemoteID { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
860 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
861
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
862 class RemoteObjectReference : IObjectReferenceBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
863 int refcnt = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
864 public UInt32 ID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
865 public Object Target { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
866 public int RefCnt { get { return refcnt; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
867 public int AddRef() { return Interlocked.Increment(ref refcnt); }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
868 public int Release(int count) { return Interlocked.Add(ref refcnt, -count); }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
869 public Boolean IsLocal { get { return true; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
870 public UInt32 RemoteID { get { return ID | 0x80000000; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
871 public RemoteObjectReference(UInt32 id, Object obj) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
872 if ((id & 0x80000000) != 0) throw new InvalidOperationException("The Object ID is invalid");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
873 this.ID = id;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
874 this.Target = obj;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
875 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
876 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
877
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
878 interface IProxyBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
879 RemotingManager Manager { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
880 UInt32 ID { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
881 ProxyObjectReference ObjectReference { get; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
882 Object GetTransparentProxy();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
883 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
884 class ProxyObjectReference : IObjectReferenceBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
885 int refcnt = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
886 WeakReference targetref;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
887 public UInt32 ID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
888 public RemotingManager Manager { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
889 public Object Target {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
890 get {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
891 IProxyBase proxy = this.Proxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
892 if (proxy == null) return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
893 return proxy.GetTransparentProxy();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
894 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
895 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
896 public IProxyBase Proxy {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
897 get {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
898 if (targetref == null) return null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
899 return (IProxyBase)targetref.Target;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
900 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
901 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
902 public int RefCnt { get { return refcnt; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
903 public int AddRef() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
904 int newcnt = Interlocked.Increment(ref refcnt);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
905 if (newcnt > 10000 && Interlocked.CompareExchange(ref refcnt, 1, newcnt) == newcnt) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
906 Manager.ProxyReleaseObject(this, newcnt - 1);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
907 newcnt = 1;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
908 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
909 return newcnt;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
910 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
911 public int Release(int count) { return Interlocked.Add(ref refcnt, -count); }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
912 public Boolean IsLocal { get { return false; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
913 public UInt32 RemoteID { get { return ID & 0x7FFFFFFF; } }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
914 public ProxyObjectReference(IProxyBase proxy) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
915 this.Manager = proxy.Manager;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
916 this.ID = proxy.ID;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
917 if ((ID & 0x80000000) == 0) throw new InvalidOperationException("The Object ID is invalid");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
918 targetref = new WeakReference(proxy);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
919 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
920 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
921 class DelegateProxy : IProxyBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
922 public ProxyObjectReference ObjectReference { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
923 public RemotingManager Manager { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
924 public UInt32 ID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
925 public Delegate Target { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
926 public MethodInfo MethodSignature { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
927 public Object GetTransparentProxy() { return Target; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
928
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
929 public DelegateProxy(RemotingManager manager, UInt32 objid, MethodInfo methodinfo, Type delegateType, DynamicMethod methodBuilder) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
930 this.Manager = manager;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
931 this.ID = objid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
932 this.MethodSignature = methodinfo;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
933 Delegate mi = methodBuilder.CreateDelegate(delegateType, this);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
934 ObjectReference = new ProxyObjectReference(this);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
935 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
936 ~DelegateProxy() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
937 Manager.ProxyReleaseObject(ObjectReference);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
938 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
939 private Object DoCall(Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
940 return Manager.ProxyMakeCallDelegate(this, args);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
941 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
942 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
943 class FWProxy : RealProxy, IRemotingTypeInfo, IProxyBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
944 public RemotingManager Manager { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
945 public UInt32 ID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
946 public ProxyObjectReference ObjectReference { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
947
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
948 public FWProxy(RemotingManager manager, UInt32 objid) : base(typeof(MarshalByRefObject)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
949 this.Manager = manager;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
950 this.ID = objid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
951 this.ObjectReference = new ProxyObjectReference(this);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
952 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
953
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
954 ~FWProxy() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
955 Manager.ProxyReleaseObject(ObjectReference);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
956 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
957
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
958 public string TypeName { get; set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
959
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
960 public override IMessage Invoke(IMessage msg) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
961 IMethodCallMessage methodCallMessage = msg as IMethodCallMessage;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
962 if (methodCallMessage != null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
963 Object r = Manager.ProxyMakeCall(this, (MethodInfo)methodCallMessage.MethodBase, methodCallMessage.Args);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
964 return new ReturnMessage(r, null, 0, null, methodCallMessage);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
965 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
966 throw new NotImplementedException();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
967 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
968
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
969 public bool CanCastTo(Type fromType, object o) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
970 if (fromType == typeof(ISerializable)) return false;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
971 return Manager.ProxyCanCastTo(this, fromType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
972 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
973 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
974 class ProxyBase : IProxyBase {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
975 public RemotingManager Manager { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
976 public UInt32 ID { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
977 public ProxyObjectReference ObjectReference { get; private set; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
978 public Object GetTransparentProxy() { return this; }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
979
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
980 public void Init(RemotingManager manager, UInt32 objid) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
981 this.Manager = manager;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
982 this.ID = objid;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
983 this.ObjectReference = new ProxyObjectReference(this);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
984 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
985
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
986 protected Object DoCall(RuntimeMethodHandle methodh, Object[] args) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
987 MethodInfo meth = (MethodInfo)MethodInfo.GetMethodFromHandle(methodh);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
988 return Manager.ProxyMakeCall(this, meth, args);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
989 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
990
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
991 ~ProxyBase() {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
992 Manager.ProxyReleaseObject(ObjectReference);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
993 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
994 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
995
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
996 private IProxyBase CreateDelegateProxy(UInt32 objid, Type deltype) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
997 MethodInfo newMethod = deltype.GetMethod("Invoke");
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
998 ParameterInfo[] parameters = newMethod.GetParameters();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
999 Type[] mparams = ArrayUtil.Merge(new Type[1] { typeof(DelegateProxy) }, Array.ConvertAll(parameters, delegate(ParameterInfo pi) { return pi.ParameterType; }));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1000 DynamicMethod methodBuilder = new DynamicMethod(String.Empty, newMethod.ReturnType, mparams, typeof(DelegateProxy));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1001 ILGenerator ilGenerator = methodBuilder.GetILGenerator();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1002 GenerateProxyMethodCode(ilGenerator, parameters, newMethod.ReturnType, typeof(DelegateProxy), "DoCall", null);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1003 return new DelegateProxy(this, objid, newMethod, deltype, methodBuilder);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1004 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1005
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1006 private IProxyBase CreateObjectProxy(UInt32 objid, String[] typeNames) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1007 DebugLog("Create proxy for remote object {0}", objid);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1008 IProxyBase proxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1009 if (true) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1010 proxy = new FWProxy(this, objid);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1011 } else {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1012 Type[] types = new Type[typeNames.Length];
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1013 int j = 0;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1014 for (int i = 0; i < typeNames.Length; i++) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1015 Type t = Type.GetType(typeNames[i], false);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1016 if (t == null || !t.IsInterface) continue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1017 types[j] = t;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1018 j++;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1019 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1020 Array.Resize(ref types, j);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1021 Type proxyType = GetProxyType(types);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1022 proxy = (ProxyBase)Activator.CreateInstance(proxyType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1023 ((ProxyBase)proxy).Init(this, objid);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1024 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1025 return proxy;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1026 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1027
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1028 private static ModuleBuilder moduleBuilder = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1029 private static Dictionary<String, Type> proxyCache = null;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1030 private static Type GetProxyType(Type[] interfaceTypes) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1031 Type proxyType;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1032 String key = String.Join("&", Array.ConvertAll(interfaceTypes, delegate(Type t) { return t.Name; }));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1033 lock (typeof(RemotingManager)) if (proxyCache == null) proxyCache = new Dictionary<String, Type>();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1034 lock (proxyCache) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1035 if (!proxyCache.TryGetValue(key, out proxyType)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1036 proxyType = GenerateProxyType(key, interfaceTypes);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1037 proxyCache.Add(key, proxyType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1038 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1039 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1040 return proxyType;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1041 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1042 private static Type GenerateProxyType(String name, Type[] interfaceTypes) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1043 lock (typeof(RemotingManager)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1044 if (moduleBuilder == null) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1045 AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("UCIS.Remoting.Proxies"), AssemblyBuilderAccess.Run);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1046 moduleBuilder = assembly.DefineDynamicModule("UCIS.Remoting.Proxies", false);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1047 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1048 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1049 TypeBuilder typeBuilder = moduleBuilder.DefineType(
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1050 name.Length == 0 ? "UndefinedProxy" : name, //mono does not like types with no name!
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1051 TypeAttributes.NotPublic | TypeAttributes.Sealed,
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1052 typeof(ProxyBase),
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1053 interfaceTypes);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1054 foreach (Type interfaceType in interfaceTypes) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1055 foreach (MethodInfo method in interfaceType.GetMethods()) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1056 GenerateProxyMethod(typeBuilder, method);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1057 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1058 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1059 return typeBuilder.CreateType();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1060 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1061 private static void GenerateProxyMethod(TypeBuilder typeBuilder, MethodInfo newMethod) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1062 if (newMethod.IsGenericMethod) newMethod = newMethod.GetGenericMethodDefinition();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1063 ParameterInfo[] parameters = newMethod.GetParameters();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1064 Type[] parameterTypes = Array.ConvertAll(parameters, delegate(ParameterInfo parameter) { return parameter.ParameterType; });
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1065
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1066 MethodBuilder methodBuilder = typeBuilder.DefineMethod(
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1067 "Impl_" + newMethod.DeclaringType.Name + "_" + newMethod.Name,
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1068 MethodAttributes.Public | MethodAttributes.Virtual,
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1069 newMethod.ReturnType,
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1070 parameterTypes);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1071 typeBuilder.DefineMethodOverride(methodBuilder, newMethod);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1072
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1073 if (newMethod.IsGenericMethod) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1074 methodBuilder.DefineGenericParameters(Array.ConvertAll(newMethod.GetGenericArguments(), delegate(Type type) { return type.Name; }));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1075 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1076
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1077 ILGenerator ilGenerator = methodBuilder.GetILGenerator();
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1078 GenerateProxyMethodCode(ilGenerator, parameters, newMethod.ReturnType, typeof(ProxyBase), "DoCall", newMethod);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1079 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1080 private static void GenerateProxyMethodCode(ILGenerator ilGenerator, ParameterInfo[] parameters, Type returnType, Type baseType, String baseMethod, MethodInfo methodRef) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1081 LocalBuilder localBuilder = ilGenerator.DeclareLocal(typeof(Object[]));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1082 ilGenerator.Emit(OpCodes.Ldc_I4, parameters.Length);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1083 ilGenerator.Emit(OpCodes.Newarr, typeof(Object));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1084 ilGenerator.Emit(OpCodes.Stloc, localBuilder);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1085 for (int i = 0; i < parameters.Length; i++) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1086 if (parameters[i].ParameterType.IsByRef) continue;
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1087 ilGenerator.Emit(OpCodes.Ldloc, localBuilder);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1088 ilGenerator.Emit(OpCodes.Ldc_I4, i);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1089 ilGenerator.Emit(OpCodes.Ldarg, i + 1);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1090 if (parameters[i].ParameterType.IsValueType) ilGenerator.Emit(OpCodes.Box, parameters[i].ParameterType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1091 ilGenerator.Emit(OpCodes.Stelem_Ref);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1092 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1093 ilGenerator.Emit(OpCodes.Ldarg_0);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1094 if (methodRef != null) ilGenerator.Emit(OpCodes.Ldtoken, methodRef);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1095 ilGenerator.Emit(OpCodes.Ldloc, localBuilder);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1096 ilGenerator.Emit(OpCodes.Call, baseType.GetMethod(baseMethod, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic));
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1097 if (returnType == typeof(void)) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1098 ilGenerator.Emit(OpCodes.Pop);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1099 } else if (returnType.IsValueType) {
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1100 ilGenerator.Emit(OpCodes.Unbox_Any, returnType);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1101 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1102 ilGenerator.Emit(OpCodes.Ret);
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1103 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1104 #endregion
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1105 }
92e09198e7e7 Added Remoting code
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1106 }