@@ -43,7 +43,7 @@ function user %#codegen
43
43
44
44
% now we can launch a couple of threads, see thread1.m and thread2.m
45
45
% launching returns a thread id, a small integer
46
- t1 = launch('thread1', 24) % pass a value to this thread
46
+ t1 = launch('thread1')
47
47
stllog('thread id %d', t1)
48
48
t2 = launch('thread2')
49
49
stllog('thread id %d', t2)
@@ -62,7 +62,7 @@ function user %#codegen
62
62
63
63
% launch a new thread, see thread3.m
64
64
% it just waits for the semaphore, then prints a message
65
- t3 = launch('thread3', 42 );
65
+ t3 = launch('thread3');
66
66
stllog('thread id %d', t3);
67
67
68
68
sleep(2);
77
77
78
78
` thread1.m `
79
79
``` matlab
80
- function thread1(arg ) %#codegen
80
+ function thread1() %#codegen
81
81
for i=1:10
82
- stllog('hello from thread1, arg=%d, id #%d', arg , self());
82
+ stllog('hello from thread1, id #%d', self());
83
83
sleep(1)
84
84
end
85
85
end
114
114
The key parts of this file is the last line
115
115
116
116
``` matlab
117
- codegen user.m thread1.m -args int32(0) thread2.m thread3.m -config cfg
117
+ codegen user.m thread1.m thread2.m thread3.m -config cfg
118
118
```
119
- There are four files provided to ` codegen ` . The first is the user's "main" function which is executed when the executable is run. Then we list the three additional threads. Note that ` thread1.m ` has an attribute ` -args int32(0) ` which specifies that this function takes an ` int32 ` argument .
119
+ There are four files provided to ` codegen ` . The first is the user's "main" function -- the file ` user.m ` -- which is executed when the executable is run. Then we list the three additional threads.
120
120
121
121
The earlier lines in ` make.m ` simply configure the build process which is captured in the state of the ` coder.config ` object ` cfg ` which is passed as the last argument to ` codegen ` .
122
122
@@ -126,77 +126,129 @@ The result is an executable `user` in the current directory which we can run
126
126
``` shellsession
127
127
% ./user bob alice
128
128
hello world
129
- got 4 arguments
129
+ got 3 arguments
130
130
arg 0: ./user
131
131
arg 1: bob
132
132
arg 2: alice
133
- arg 3: 123.5
134
- 2018-08-27 09:24:48.460991 [user] hello world
135
- 2018-08-27 09:24:48.461848 [user] hello world
136
- 2018-08-27 09:24:48.461932 [user] thread id 1
137
- 2018-08-27 09:24:48.461953 [user] thread id 2
138
- 2018-08-27 09:24:48.461959 [user] waiting for thread #1 <thread1>
139
- 2018-08-27 09:24:48.461964 [thread1] starting posix thread <thread1> (0xA1620A0)
140
- 2018-08-27 09:24:48.461968 [thread2] starting posix thread <thread2> (0xA162160)
141
- 2018-08-27 09:24:48.462000 [thread2] hello from thread2, id #2
142
- 2018-08-27 09:24:48.462022 [thread1] hello from thread1, arg=24 , id #1
143
- 2018-08-27 09:24:49.462176 [thread1] hello from thread1, arg=24 , id #1
144
- 2018-08-27 09:24:50.463095 [thread2] hello from thread2, id #2
145
- 2018-08-27 09:24:50.463103 [thread1] hello from thread1, arg=24 , id #1
146
- 2018-08-27 09:24:51.466686 [thread1] hello from thread1, arg=24 , id #1
147
- 2018-08-27 09:24:52.466779 [thread2] hello from thread2, id #2
148
- 2018-08-27 09:24:52.469230 [thread1] hello from thread1, arg=24 , id #1
149
- 2018-08-27 09:24:53.469441 [thread1] hello from thread1, arg=24 , id #1
150
- 2018-08-27 09:24:54.469791 [thread1] hello from thread1, arg=24 , id #1
151
- 2018-08-27 09:24:54.469757 [thread2] hello from thread2, id #2
152
- 2018-08-27 09:24:55.472021 [thread1] hello from thread1, arg=24 , id #1
153
- 2018-08-27 09:24:56.473077 [thread2 ] hello from thread2 , id #2
154
- 2018-08-27 09:24:56.475361 [thread1 ] hello from thread1, arg=24, id #1
155
- 2018-08-27 09:24:57.476450 [thread1] hello from thread1, arg=24 , id #1
156
- 2018-08-27 09:24:58.477224 [thread2] hello from thread2, id #2
157
- 2018-08-27 09:24:58.477225 [thread1] posix thread <thread1> has returned
158
- 2018-08-27 09:24:58.477471 [user] thread complete #1 <thread1>
159
- 2018-08-27 09:25:00.479498 [thread2] hello from thread2, id #2
160
- 2018-08-27 09:25:02.480656 [thread2] hello from thread2, id #2
161
- 2018-08-27 09:25:03.479300 [user] cancelling thread #2 <thread2>
162
- 2018-08-27 09:25:03.479371 [user] waiting for thread #2 <thread2>
163
- 2018-08-27 09:25:03.479435 [user] thread complete #2 <thread2>
164
- 2018-08-27 09:25:05.479844 [user] creating semaphore #0 <sem1>
165
- 2018-08-27 09:25:05.479977 [user] sem id 0
166
- 2018-08-27 09:25:06.481025 [user] thread id 1
167
- 2018-08-27 09:25:06.481079 [thread3] starting posix thread <thread3> (0xA162220)
168
- 2018-08-27 09:25:06.481109 [thread3] waiting for semaphore #0 <sem1>
169
- 2018-08-27 09:25:08.484186 [user] posting semaphore #0 <sem1>
170
- 2018-08-27 09:25:08.484330 [thread3] semaphore wait complete #0
171
- 2018-08-27 09:25:08.484359 [thread3] hello from thread 3
172
- 2018-08-27 09:25:08.484369 [thread3] waiting for semaphore #0 <sem1>
173
- 2018-08-27 09:25:09.485037 [user] posting semaphore #0 <sem1>
174
- 2018-08-27 09:25:09.485127 [thread3] semaphore wait complete #0
175
- 2018-08-27 09:25:09.485140 [thread3] hello from thread 3
176
- 2018-08-27 09:25:09.485149 [thread3] waiting for semaphore #0 <sem1>
133
+ 2018-09-16 16:52:38.281053 [user] hello world
134
+ 2018-09-16 16:52:38.281793 [user] hello world
135
+ 2018-09-16 16:52:38.281841 [user] thread id 1
136
+ 2018-09-16 16:52:38.281850 [thread1] starting posix thread <thread1> (0xFCD5A10)
137
+ 2018-09-16 16:52:38.281860 [user] thread id 2
138
+ 2018-09-16 16:52:38.281869 [thread2] starting posix thread <thread2> (0xFCD5B10)
139
+ 2018-09-16 16:52:38.281876 [user] waiting for thread #1 <thread1>
140
+ 2018-09-16 16:52:38.281914 [thread1] hello from thread1
141
+ 2018-09-16 16:52:38.281927 [thread2] hello from thread2, id #2
142
+ 2018-09-16 16:52:38.281963 [thread1] hello from thread1, id #1
143
+ 2018-09-16 16:52:39.286172 [thread1] hello from thread1, id #1
144
+ 2018-09-16 16:52:40.285643 [thread2] hello from thread2, id #2
145
+ 2018-09-16 16:52:40.286787 [thread1] hello from thread1, id #1
146
+ 2018-09-16 16:52:41.286863 [thread1] hello from thread1, id #1
147
+ 2018-09-16 16:52:42.286156 [thread2] hello from thread2, id #2
148
+ 2018-09-16 16:52:42.287227 [thread1] hello from thread1, id #1
149
+ 2018-09-16 16:52:43.287423 [thread1] hello from thread1, id #1
150
+ 2018-09-16 16:52:44.289092 [thread1] hello from thread1, id #1
151
+ 2018-09-16 16:52:44.289092 [thread2] hello from thread2, id #2
152
+ 2018-09-16 16:52:45.289178 [thread1] hello from thread1, id #1
153
+ 2018-09-16 16:52:46.292749 [thread1 ] hello from thread1 , id #1
154
+ 2018-09-16 16:52:46.292746 [thread2 ] hello from thread2, id #2
155
+ 2018-09-16 16:52:47.297975 [thread1] hello from thread1, id #1
156
+ 2018-09-16 16:52:48.297823 [thread2] hello from thread2, id #2
157
+ 2018-09-16 16:52:48.299590 [thread1] MATLAB function <thread1> has returned, thread exiting
158
+ 2018-09-16 16:52:48.299666 [user] thread complete #1 <thread1>
159
+ 2018-09-16 16:52:50.302948 [thread2] hello from thread2, id #2
160
+ 2018-09-16 16:52:52.307330 [thread2] hello from thread2, id #2
161
+ 2018-09-16 16:52:53.301583 [user] cancelling thread #2 <thread2>
162
+ 2018-09-16 16:52:53.301710 [user] waiting for thread #2 <thread2>
163
+ 2018-09-16 16:52:53.301815 [user] thread complete #2 <thread2>
164
+ 2018-09-16 16:52:55.302909 [user] creating semaphore #0 <sem1>
165
+ 2018-09-16 16:52:55.302950 [user] sem id 0
166
+ 2018-09-16 16:52:56.307164 [user] thread id 1
167
+ 2018-09-16 16:52:56.307204 [thread3] starting posix thread <thread3> (0xFCD5BD0)
168
+ 2018-09-16 16:52:56.307233 [thread3] waiting for semaphore #0 <sem1>
169
+ 2018-09-16 16:52:58.311708 [user] posting semaphore #0 <sem1>
170
+ 2018-09-16 16:52:58.311830 [thread3] semaphore wait complete #0
171
+ 2018-09-16 16:52:58.311845 [thread3] hello from thread 3
172
+ 2018-09-16 16:52:58.311855 [thread3] waiting for semaphore #0 <sem1>
173
+ 2018-09-16 16:52:59.312160 [user] posting semaphore #0 <sem1>
174
+ 2018-09-16 16:52:59.312197 [thread3] semaphore wait complete #0
175
+ 2018-09-16 16:52:59.312204 [thread3] hello from thread 3
176
+ 2018-09-16 16:52:59.312208 [thread3] waiting for semaphore #0 <sem1>
177
177
```
178
178
179
179
## Example 2: Web server
180
+ The user's main program is quite simple:
181
+ ``` matlab
182
+ function user() %#codegen
183
+ stl.log('user program starts');
184
+ webserver(8080, 'myserver');
185
+ stl.sleep(60);
186
+ end
187
+ ```
188
+
189
+ Pointing a browser at port 8080 on the host running the program interacts with the MATLAB webserver code which is fairly clearly expressed.
180
190
``` matlab
181
191
function myserver() % called on every page request
182
192
switch (webserver.url())
183
193
case '/'
184
- webserver.html('hello world'); % display a simple string
185
- case '/bob'
186
- webserver.html('<html><body>hello <b>from</b> /bob</body></html>');
187
- a = webserver.getarg('a'); % test for argument of the form ?a=X
194
+ stl.log('in /')
195
+ webserver.html('home here');
196
+ case '/page1'
197
+ stl.log('in /page1');
198
+ if webserver.isGET()
199
+ stl.log('GET request');
200
+ end
201
+ a = webserver.getarg('a');
188
202
if ~isempty(a)
189
- stllog ('a = %s', cstring(a));
203
+ stl.log ('a = %s', cstring(a));
190
204
end
191
- case '/alice'
205
+ webserver.html('<html><body>hello <b>from</b> /page1</body></html>');
206
+ case '/page2'
207
+ stl.log('in /page2')
192
208
vals.a = 1;
193
209
vals.b = 2;
194
- webserver.template('templates/alice.html', vals); % create a templated response
195
- case '/duck':
196
- webserver.file('duck.jpg', 'image/jpeg'); % return an image
210
+ webserver.template('templates/page2.html', vals);
211
+ case '/duck'
212
+ webserver.file('duck.jpg', 'image/jpeg');
213
+ case '/input'
214
+ if webserver.isPOST()
215
+ stl.log('POST request');
216
+ foo = webserver.postarg('Foo');
217
+ stl.log('foo = %s', cstring(foo));
218
+ else
219
+ stl.log('GET request');
220
+ end
221
+ webserver.template('templates/input.html');
222
+ end
223
+ end
224
+ ```
225
+ The switch statement is used to select the code according to the URL given, and other methods provide access to parameters of the HTTP request.
226
+ <hr />
227
+ ![ page1] ( doc/page1.png )
228
+ ``` shell
229
+ 2018-09-16 15:54:28.635937 [user] user program starts
230
+ 2018-09-16 15:54:28.636843 [user] web server starting on port 8080
231
+ 2018-09-16 15:54:33.170370 [user] web: GET request using HTTP/1.1 for URL /page1
232
+ 2018-09-16 15:54:33.170410 [WEB] in /page1
233
+ 2018-09-16 15:54:33.170416 [WEB] GET request
234
+ 2018-09-16 15:54:33.170421 [WEB] a = 7
235
+ 2018-09-16 15:54:33.170425 [WEB] web_html: < html><body> hello < b> from< /b> /page1< /body></html></body></html>
236
+ ```
237
+ Note the arguements ` ?a=7&b=12 ` on the end of the URL. These are GET arguments of the form ` key=value ` , and the method ` getarg ` provides access to them by key. In this case we get the value of the key ` a ` .
238
+
239
+ Note also, that log messages from the web server function are listed as coming from the ` WEB ` thread, which is created by ` webserver() ` .
240
+ <hr />
241
+ ![ page2] ( doc/page2.png )
242
+
243
+ ``` shell
244
+ 2018-09-16 15:39:12.816790 [WEB] web: GET request using HTTP/1.1 for URL /page2
245
+ 2018-09-16 15:39:12.816822 [WEB] in /page2
246
+ 2018-09-16 15:39:12.816827 [WEB] web_setvalue: a 1
247
+ 2018-09-16 15:39:12.816849 [WEB] web_setvalue: b 2
248
+ 2018-09-16 15:39:12.816854 [WEB] web_template: templates/page2.html
197
249
```
198
250
199
- The template file looks like
251
+ The template file is sent to the browser with substitutions. The ` page2.html ` looks like
200
252
``` html
201
253
<html >
202
254
<body >
@@ -207,6 +259,53 @@ The template file looks like
207
259
</html >
208
260
```
209
261
and the values of the fields of the struct ` vals ` are substituted for the corresonding named ` TMPL_VAR ` tags.
262
+ <hr />
263
+ ![ duck] ( doc/duck.png )
264
+
265
+ ``` shell
266
+ 2018-09-16 15:36:08.881139 [WEB] web: GET request using HTTP/1.1 for URL /duck
267
+ 2018-09-16 15:36:08.881159 [WEB] web_file: duck.jpg, type image/jpeg
268
+ 2018-09-16 15:36:08.881208 [WEB] file is 83234 bytes
269
+ ```
270
+ The local file ` duck.png ` is sent to the browser as an ` image/jpeg ` filetype.
271
+ <hr />
272
+ ![ post] ( doc/post.png )
273
+
274
+ ``` shell
275
+ 2018-09-16 16:32:00.035029 [user] web: GET request using HTTP/1.1 for URL /input
276
+ 2018-09-16 16:32:00.035101 [WEB] input called
277
+ 2018-09-16 16:32:00.035109 [WEB] GET request
278
+ 2018-09-16 16:32:00.035118 [WEB] web_template: templates/input.html
279
+ 2018-09-16 16:32:04.385387 [WEB] web: POST request using HTTP/1.1 for URL /input
280
+ 2018-09-16 16:32:04.385580 [WEB] web: POST request using HTTP/1.1 for URL /input
281
+ 2018-09-16 16:32:04.385623 [WEB] POST [Foo] = 27
282
+ 2018-09-16 16:32:04.385634 [WEB] POST [button] = Button2
283
+ 2018-09-16 16:32:04.385655 [WEB] web: POST request using HTTP/1.1 for URL /input
284
+ 2018-09-16 16:32:04.385666 [WEB] input called
285
+ 2018-09-16 16:32:04.385671 [WEB] POST request
286
+ 2018-09-16 16:32:04.385676 [WEB] foo = 27
287
+ 2018-09-16 16:32:04.385681 [WEB] web_template: templates/input.html
288
+ ```
289
+ This example is rather more complex. The page is requested with a standard GET request and the HTML file ` input.html ` is returned to the browser
290
+ ``` html
291
+ <html >
292
+ <body >
293
+ <p >This is a page to test POST</p >
294
+ <form action =" " method =" post" >
295
+ <p >Enter value of foo:
296
+ <!-- POST key = Foo, POST value is entered tect -->
297
+ <input type =" text" value =" 0" name =" Foo" />
298
+
299
+ <!-- button label is given by value, POST key = button, POST value = Button1/2 -->
300
+ <p ><input type =" submit" value =" Button1" name =" button" /></p >
301
+ <p ><input type =" submit" value =" Button2" name =" button" /></p >
302
+ </form >
303
+ </body >
304
+ </html >
305
+ ```
306
+ The browser displays a form with a text input box and two buttons. When either button (or a newline) is entered, the browser sends the contents of the text box and the button that pushed as ` name=value ` pairs. The postarg method gets the value of the textbox which has ` name=Foo ` . The diagnostic messages show that ` Button2 ` was pressed, and this could be tested by accessing the value for the name ` button ` .
307
+
308
+ The POST request must return a value, and in this case it is template file.
210
309
211
310
---
212
311
Created using Sublime3 with awesome packages ` MarkdownEditing ` , ` MarkdownPreview ` and ` Livereload ` for WYSIWYG markdown editing.
0 commit comments