Mercurial > projects > ldc
comparison tango/tango/net/cluster/NetworkCall.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2007 Tango. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: April 2007: Initial release | |
8 | |
9 author: h3r3tic, Kris | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.net.cluster.NetworkCall; | |
14 | |
15 private import tango.core.Traits; | |
16 private import tango.core.Thread; | |
17 | |
18 private import tango.net.cluster.NetworkMessage; | |
19 | |
20 protected import tango.io.protocol.model.IReader, | |
21 tango.io.protocol.model.IWriter; | |
22 | |
23 protected import tango.net.cluster.model.IChannel; | |
24 | |
25 | |
26 /******************************************************************************* | |
27 | |
28 task harness, for initiating the send | |
29 | |
30 *******************************************************************************/ | |
31 | |
32 class NetworkCall : NetworkMessage | |
33 { | |
34 /*********************************************************************** | |
35 | |
36 ***********************************************************************/ | |
37 | |
38 void send (IChannel channel = null) | |
39 { | |
40 if (channel) | |
41 channel.execute (this); | |
42 else | |
43 { | |
44 auto x = cast(IChannel) Thread.getLocal(0); | |
45 if (x) | |
46 x.execute (this); | |
47 else | |
48 execute; | |
49 } | |
50 } | |
51 } | |
52 | |
53 | |
54 /******************************************************************************* | |
55 | |
56 Template for RPC glue | |
57 | |
58 *******************************************************************************/ | |
59 | |
60 class NetCall(alias realFunc) : NetworkCall | |
61 { | |
62 alias ParameterTupleOf!(realFunc) Params; | |
63 alias ReturnTypeOf!(realFunc) RetType; | |
64 | |
65 static if (!is(RetType == void)) { | |
66 RetType result; | |
67 } | |
68 Params params; | |
69 | |
70 | |
71 override char[] toString() { | |
72 return signatureOfFunc!(realFunc); | |
73 } | |
74 | |
75 RetType opCall(Params params, IChannel channel = null) { | |
76 foreach (i, _dummy; this.params) { | |
77 this.params[i] = params[i]; | |
78 } | |
79 send (channel); | |
80 | |
81 static if (!is(RetType == void)) { | |
82 return result; | |
83 } | |
84 } | |
85 | |
86 override void execute() { | |
87 static if (!is(RetType == void)) { | |
88 result = realFunc(params); | |
89 } else { | |
90 realFunc(params); | |
91 } | |
92 } | |
93 | |
94 override void read(IReader input) { | |
95 static if (!is(RetType == void)) { | |
96 input(result); | |
97 } | |
98 foreach (i, _dummy; params) input(params[i]); | |
99 } | |
100 | |
101 override void write(IWriter output) { | |
102 static if (!is(RetType == void)) { | |
103 output(result); | |
104 } | |
105 foreach (i, _dummy; params) output(params[i]); | |
106 } | |
107 } | |
108 | |
109 | |
110 /******************************************************************************* | |
111 | |
112 Magic to get a clean function signature | |
113 | |
114 *******************************************************************************/ | |
115 | |
116 private { | |
117 struct Wrapper(alias fn) {} | |
118 const char[] WrapperPrefix = `__T7Wrapper`; | |
119 | |
120 | |
121 uint parseUint(char[] str) { | |
122 int res = 0; | |
123 foreach (c; str) { | |
124 res *= 10; | |
125 res += c - '0'; | |
126 } | |
127 return res; | |
128 } | |
129 | |
130 | |
131 char[] sliceOffSegment(inout char[] str) { | |
132 assert (str.length > 0 && str[0] >= '0' && str[0] <= '9'); | |
133 | |
134 int lenEnd = 0; | |
135 for (; str[lenEnd] >= '0' && str[lenEnd] <= '9'; ++lenEnd) {} | |
136 | |
137 char[] lenStr = str[0..lenEnd]; | |
138 uint segLen = parseUint(lenStr); | |
139 str = str[lenEnd .. $]; | |
140 | |
141 char[] res = str[0..segLen]; | |
142 str = str[segLen .. $]; | |
143 return res; | |
144 } | |
145 | |
146 | |
147 char[] digOutWrapper(char[] wrapped) { | |
148 wrapped = wrapped[1..$]; // skip the 'S' | |
149 char[] seg; | |
150 | |
151 do { | |
152 seg = sliceOffSegment(wrapped); | |
153 } while (seg.length < WrapperPrefix.length || seg[0..WrapperPrefix.length] != WrapperPrefix); | |
154 | |
155 return seg[WrapperPrefix.length .. $]; | |
156 } | |
157 | |
158 | |
159 char[] demangleDFunc(char[] mangled) { | |
160 char[] res = sliceOffSegment(mangled); | |
161 | |
162 while (mangled.length > 0 && mangled[0] >= '0' && mangled[0] <= '9') { | |
163 res ~= '.' ~ sliceOffSegment(mangled); | |
164 } | |
165 return res; | |
166 } | |
167 | |
168 | |
169 char[] nameOf_impl(char[] wrapped) { | |
170 char[] wrapper = digOutWrapper(wrapped)[1..$]; // skip the 'S' | |
171 char[] mangled = sliceOffSegment(wrapper); | |
172 | |
173 if (mangled.length > 2 && mangled[0..2] == `_D`) { | |
174 // D func | |
175 return demangleDFunc(mangled[2..$]); | |
176 } else { | |
177 return mangled; // C func | |
178 } | |
179 } | |
180 | |
181 | |
182 int match_param_(char[] str) { | |
183 if (str.length < `_param_0`.length) return 0; | |
184 | |
185 int numDigits = 0; | |
186 while (str[$-1-numDigits] >= '0' && str[$-1-numDigits] <= '9') { | |
187 ++numDigits; | |
188 } | |
189 | |
190 if (0 == numDigits) return 0; | |
191 | |
192 if (str.length >= `_param_`.length + numDigits && str[$-`_param_`.length-numDigits .. $-numDigits] == `_param_`) { | |
193 return `_param_`.length + numDigits; | |
194 } else { | |
195 return 0; | |
196 } | |
197 } | |
198 | |
199 | |
200 // sometimes the param lists have ugly _param_[0-9]+ names in them... | |
201 char[] tidyTupleStringof(char[] str) { | |
202 char[] res; | |
203 for (int i = 0; i < str.length; ++i) { | |
204 char c = str[i]; | |
205 | |
206 if (c == ')' || c == ',') { | |
207 if (auto len = match_param_(str[0..i])) { | |
208 // len is the length of the _param_[0-9]+ thing | |
209 int start = i-1-len; | |
210 str = str[0..start] ~ str[i..$]; | |
211 i -= len; | |
212 } | |
213 } | |
214 } | |
215 | |
216 return str; | |
217 } | |
218 | |
219 | |
220 template nameOfFunc(alias fn) { | |
221 static assert (is(typeof(fn) == function)); | |
222 const char[] nameOfFunc = nameOf_impl((Wrapper!(fn)).mangleof); | |
223 } | |
224 | |
225 | |
226 template signatureOfFunc(alias fn) { | |
227 static assert (is(typeof(fn) == function)); | |
228 const char[] signatureOfFunc = ReturnTypeOf!(fn).stringof ~ ' ' ~ nameOfFunc!(fn) ~ tidyTupleStringof(ParameterTupleOf!(fn).stringof); | |
229 } | |
230 } |