|
35 | 35 | {1 Understanding cancelation} |
36 | 36 |
|
37 | 37 | A central idea of Picos is to provide a collection of building blocks for |
38 | | - parallelism safe cancelation. Consider the following characteristic |
39 | | - example: |
| 38 | + parallelism safe cancelation. |
| 39 | +
|
| 40 | + Consider the following motivating example: |
40 | 41 |
|
41 | 42 | {@ocaml skip[ |
42 | 43 | Mutex.protect mutex begin fun () -> |
|
48 | 49 |
|
49 | 50 | Assume that the fiber executing the above computation might be canceled, at |
50 | 51 | any point, by another fiber running in parallel. How could that be done |
51 | | - both effectively and safely? |
| 52 | + ensuring both safety and liveness? |
52 | 53 |
|
53 | | - - To be effective, cancelation should take effect as soon as possible. In |
54 | | - this case, cancelation should take effect even during the |
55 | | - {{!Picos_std_sync.Mutex.lock} [Mutex.lock]} inside |
56 | | - {{!Picos_std_sync.Mutex.protect} [Mutex.protect]} and the |
57 | | - {{!Picos_std_sync.Condition.wait} [Condition.wait]} operations when the |
58 | | - fiber might be in a suspended state awaiting for a signal to continue. |
59 | | - - To be safe, cancelation should not leave the program in an invalid state |
| 54 | + - For safety, cancelation should not leave the program in an invalid state |
60 | 55 | or cause the program to leak memory. In this case, the ownership of the |
61 | 56 | mutex must be transferred to the next fiber or be left unlocked and no |
62 | 57 | references to unused objects must be left in the mutex or the condition |
63 | 58 | variable. |
64 | 59 |
|
65 | | - Picos allows {{!Picos_std_sync.Mutex} [Mutex]} and |
66 | | - {{!Picos_std_sync.Condition} [Condition]} to be implemented such that |
67 | | - cancelation may safely take effect at or during calls to |
68 | | - {{!Picos_std_sync.Mutex.lock} [Mutex.lock]} and |
69 | | - {{!Picos_std_sync.Condition.wait} [Condition.wait]}. |
| 60 | + - For liveness, cancelation should take effect as soon as possible. In this |
| 61 | + case, cancelation should take effect even during the |
| 62 | + {{!Picos_std_sync.Mutex.lock} [Mutex.lock]} inside |
| 63 | + {{!Picos_std_sync.Mutex.protect} [Mutex.protect]} and the |
| 64 | + {{!Picos_std_sync.Condition.wait} [Condition.wait]} operations when the |
| 65 | + fiber might be in a suspended state awaiting for a signal to continue. |
| 66 | +
|
| 67 | + Here is another motivating example: |
| 68 | +
|
| 69 | + {@ocaml skip[ |
| 70 | + (* ... allocate resources ... *) |
| 71 | + Fun.protect ~finally begin fun () -> |
| 72 | + Flock.join_after begin fun () -> |
| 73 | + (* ... *) |
| 74 | + Flock.fork begin fun () -> |
| 75 | + (* ... may use resources ... *) |
| 76 | + end; |
| 77 | + (* ... *) |
| 78 | + end; |
| 79 | + (* ... resources no longer used ... *) |
| 80 | + end |
| 81 | + ]} |
| 82 | +
|
| 83 | + The idea is that the main or parent fiber allocates some resources, which |
| 84 | + are then used by child fibers running in parallel. What should happen when |
| 85 | + the main fiber gets canceled? We again have both safety and liveness |
| 86 | + concerns: |
| 87 | +
|
| 88 | + - For safety, to ensure that resources are not finalized prematurely, the |
| 89 | + {{!Picos_std_structured.Flock.join_after} [Flock.join_after]} call must |
| 90 | + not return or raise before all of the child fibers have terminated. |
| 91 | +
|
| 92 | + - For liveness, when the parent fiber gets canceled, we'd like all the child |
| 93 | + fibers to also get canceled. |
| 94 | +
|
| 95 | + Picos is designed to allow the above motivating examples and more to be |
| 96 | + implemented correctly addressing both safety and liveness. |
70 | 97 |
|
71 | 98 | {2 Cancelation in Picos} |
72 | 99 |
|
|
0 commit comments