]> Cypherpunks.ru repositories - goredo.git/blob - js.go
Fix JS deadlock and various optimizations
[goredo.git] / js.go
1 /*
2 goredo -- redo implementation on pure Go
3 Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 // Jobserver
19
20 package main
21
22 import "os"
23
24 var (
25         JSR *os.File
26         JSW *os.File
27 )
28
29 func jsInit() {
30         jsrRaw := os.Getenv(RedoJSRFdEnv)
31         jswRaw := os.Getenv(RedoJSWFdEnv)
32         if (jsrRaw == "" && jswRaw != "") || (jsrRaw != "" && jswRaw == "") {
33                 panic("both JSR and JSW must be set")
34         }
35         if jsrRaw == "NO" {
36                 // infinite jobs
37                 return
38         }
39         if jsrRaw != "" {
40                 JSR = mustParseFd(jsrRaw, "JSR")
41                 JSW = mustParseFd(jswRaw, "JSW")
42                 jsRelease("ifchange entered")
43                 return
44         }
45         if *JobsN == 0 {
46                 // infinite jobs
47                 return
48         }
49         var err error
50         JSR, JSW, err = os.Pipe()
51         if err != nil {
52                 panic(err)
53         }
54         for i := uint(0); i < *JobsN; i++ {
55                 jsRelease("initial fill")
56         }
57 }
58
59 func jsRelease(ctx string) {
60         if JSW == nil {
61                 return
62         }
63         trace(CJS, "release from %s", ctx)
64         if n, err := JSW.Write([]byte{0}); err != nil || n != 1 {
65                 panic("can not write JSW")
66         }
67 }
68
69 func jsAcquire(ctx string) {
70         if JSR == nil {
71                 return
72         }
73         trace(CJS, "acquire for %s", ctx)
74         if n, err := JSR.Read([]byte{0}); err != nil || n != 1 {
75                 panic("can not read JSR")
76         }
77         trace(CJS, "acquired for %s", ctx)
78 }