Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dc48c96

Browse filesBrowse files
committed
update README and figures
1 parent 68d09fb commit dc48c96
Copy full SHA for dc48c96

File tree

7 files changed

+160
-61
lines changed
Filter options

7 files changed

+160
-61
lines changed

‎README.md

Copy file name to clipboardExpand all lines: README.md
+160-61
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

Copy file name to clipboard
-25.4 KB
Binary file not shown.

‎doc/duck.png

Copy file name to clipboard
207 KB
Loading

‎doc/input.png

Copy file name to clipboard
58.2 KB
Loading

‎doc/page1.png

Copy file name to clipboard
51.8 KB
Loading

‎doc/page2.png

Copy file name to clipboard
21.3 KB
Loading

‎doc/post.png

Copy file name to clipboard
23.2 KB
Loading

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.