You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tinync is a simplified implementation of [nc](https://en.wikipedia.org/wiki/Netcat), which aims to demonstrate the usage of [coroutine](https://en.wikipedia.org/wiki/Coroutine) macros and their effects.
3
+
4
+
## Internals
5
+
### Declaring a Coroutine Function
6
+
At the very beginning, a coroutine function should be declared first, coroutine function is part of program that will be executed simultaneously with other coroutines. All coroutines should be specified with the macro `cr_proto`, following shows the example:
With in the coroutine, there are several macros for controlling the behavior of coroutine, following are list of them:
16
+
* `cr_begin` aims to initiate the context of coroutine when the coroutine is first invoked, or resume previous execution for the rest of invocations. This macro should be placed before other cotrolling macros except `cr_local`.
17
+
* `cr_end` ends up a coroutine that will mark the status of coroutine as finished, which could be detected outside to ensure whether a coroutine finisihed its job or not.
18
+
* `cr_wait` is used for waiting a condition happened. Once the condition it is waiting for has not happened yet, it will pause the current coroutine and switch to another.
19
+
* `cr_exit` not only yields a coroutine but also updates its state with given state.
20
+
* `cr_sys` is a wrapper of `cr_wait` which performs waiting on system calls and other functions that return -1 and set `errno`.
21
+
* `cr_local` is a marker for programmers to recognize a variable related to coroutine easily.
22
+
23
+
In `tinync.c`, we can see the combinations of these macros:
/* Wait for read system call to become successful. */
37
+
cr_sys(r = read(STDIN_FILENO, &b, 1));
38
+
if (r == 0) {
39
+
/* Wait until queue out is flushed. */
40
+
cr_wait(cr_queue_empty(out));
41
+
42
+
/* Exit the coroutine with status update as finished. */
43
+
cr_exit(1);
44
+
}
45
+
/* Wait until there is place in queue out. */
46
+
cr_wait(!cr_queue_full(out));
47
+
cr_queue_push(out, b);
48
+
}
49
+
/* End up this coroutine, status will be updated as finished. */
50
+
cr_end();
51
+
}
52
+
```
53
+
54
+
### Coroutine Context
55
+
Context is an important part for coroutine, which preserves the execution point of a coroutine that could be resumed later. To define a context for a coroutine, use `cr_context` macro and initiates it with macro `cr_context_init`. It is important to **assign an identical name to context and its corresponding function**. With example presented at the beginning, its corresponding context should be specified as follows:
56
+
```cpp
57
+
cr_context(coroutine_name) = cr_context_init();
58
+
```
59
+
60
+
### Launching and Monitoring
61
+
Now, all required preparations are done, programmers may launch a coroutine via `cr_run` macro and monitor it with `cr_status` macro. To execute several coroutines simultaneously, place `cr_run`s that launch coroutines in a loop and keep tracking their status until all of them are finished. Following shows a simple example:
62
+
```cpp
63
+
while (cr_status(coroutine_1) != CR_FINISHED &&
64
+
cr_status(coroutine_2) != CR_FINISHED &&
65
+
cr_status(coroutine_3) != CR_FINISHED) {
66
+
cr_run(coroutine_1);
67
+
cr_run(coroutine_2);
68
+
cr_run(coroutine_3);
69
+
}
70
+
```
71
+
72
+
## Run the Sample Program
73
+
Tinync is a sample program that handles several coroutines to maintain communication with remote while accept user input simultaneously. To compile it, use `make`:
74
+
```shell
75
+
$ make
76
+
```
77
+
This sample requires two terminals, let's say `T1` and `T2`. Before launching `tinync`, start `nc` in `T1` first:
78
+
```shell
79
+
$ nc -l 127.0.0.1 9000
80
+
```
81
+
Then launch `tinync` in `T2`:
82
+
```shell
83
+
$ tinync 127.0.0.1 9000
84
+
```
85
+
Now, any words typed in `T1` will be recived and presented in `T2`, and vice versa.
0 commit comments