Skip to content

Commit dc48c96

Browse files
committed
update README and figures
1 parent 68d09fb commit dc48c96

File tree

7 files changed

+160
-61
lines changed

7 files changed

+160
-61
lines changed

README.md

Lines changed: 160 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function user %#codegen
4343
4444
% now we can launch a couple of threads, see thread1.m and thread2.m
4545
% launching returns a thread id, a small integer
46-
t1 = launch('thread1', 24) % pass a value to this thread
46+
t1 = launch('thread1')
4747
stllog('thread id %d', t1)
4848
t2 = launch('thread2')
4949
stllog('thread id %d', t2)
@@ -62,7 +62,7 @@ function user %#codegen
6262
6363
% launch a new thread, see thread3.m
6464
% it just waits for the semaphore, then prints a message
65-
t3 = launch('thread3', 42);
65+
t3 = launch('thread3');
6666
stllog('thread id %d', t3);
6767
6868
sleep(2);
@@ -77,9 +77,9 @@ end
7777

7878
`thread1.m`
7979
```matlab
80-
function thread1(arg) %#codegen
80+
function thread1() %#codegen
8181
for i=1:10
82-
stllog('hello from thread1, arg=%d, id #%d', arg, self());
82+
stllog('hello from thread1, id #%d', self());
8383
sleep(1)
8484
end
8585
end
@@ -114,9 +114,9 @@ end
114114
The key parts of this file is the last line
115115

116116
```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
118118
```
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.
120120

121121
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`.
122122

@@ -126,77 +126,129 @@ The result is an executable `user` in the current directory which we can run
126126
```shellsession
127127
% ./user bob alice
128128
hello world
129-
got 4 arguments
129+
got 3 arguments
130130
arg 0: ./user
131131
arg 1: bob
132132
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>
177177
```
178178

179179
## 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.
180190
```matlab
181191
function myserver() % called on every page request
182192
switch (webserver.url())
183193
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');
188202
if ~isempty(a)
189-
stllog('a = %s', cstring(a));
203+
stl.log('a = %s', cstring(a));
190204
end
191-
case '/alice'
205+
webserver.html('<html><body>hello <b>from</b> /page1</body></html>');
206+
case '/page2'
207+
stl.log('in /page2')
192208
vals.a = 1;
193209
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
197249
```
198250

199-
The template file looks like
251+
The template file is sent to the browser with substitutions. The `page2.html` looks like
200252
```html
201253
<html>
202254
<body>
@@ -207,6 +259,53 @@ The template file looks like
207259
</html>
208260
```
209261
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.
210309

211310
---
212311
Created using Sublime3 with awesome packages `MarkdownEditing`, `MarkdownPreview` and `Livereload` for WYSIWYG markdown editing.

doc/alice.png

-25.4 KB
Binary file not shown.

doc/duck.png

207 KB
Loading

doc/input.png

58.2 KB
Loading

doc/page1.png

51.8 KB
Loading

doc/page2.png

21.3 KB
Loading

doc/post.png

23.2 KB
Loading

0 commit comments

Comments
 (0)