1
1
package solverrpc
2
2
3
3
import (
4
+ "errors"
4
5
"io"
5
6
"math/big"
6
7
"net/rpc"
@@ -13,6 +14,10 @@ import (
13
14
// Roots if the process is named differently or if an absolute path is needed.
14
15
var SolverProcess = "csppsolver"
15
16
17
+ // ErrSolverProcessExited indicates that the solver process was started, but
18
+ // has since exited (possibly due to a crash, or a signal which killed it).
19
+ var ErrSolverProcessExited = errors .New ("solver process exited" )
20
+
16
21
type solverProcess struct {
17
22
cmd * exec.Cmd
18
23
stdin io.WriteCloser
44
49
once sync.Once
45
50
onceErr error
46
51
client * rpc.Client
52
+ cmdDone = make (chan struct {})
47
53
)
48
54
49
55
func startSolver () {
@@ -68,6 +74,19 @@ func startSolver() {
68
74
stdin : stdin ,
69
75
stdout : stdout ,
70
76
})
77
+ go func () {
78
+ cmd .Wait ()
79
+ close (cmdDone )
80
+ }()
81
+ }
82
+
83
+ func checkExit () error {
84
+ select {
85
+ case <- cmdDone :
86
+ return ErrSolverProcessExited
87
+ default :
88
+ return nil
89
+ }
71
90
}
72
91
73
92
// StartSolver starts the solver's background process. This can be used to
@@ -85,6 +104,10 @@ func RootFactors(a []*big.Int, F *big.Int) ([]*big.Int, []int, error) {
85
104
return nil , nil , err
86
105
}
87
106
107
+ if err := checkExit (); err != nil {
108
+ return nil , nil , err
109
+ }
110
+
88
111
var args struct {
89
112
A []* big.Int
90
113
F * big.Int
@@ -97,6 +120,9 @@ func RootFactors(a []*big.Int, F *big.Int) ([]*big.Int, []int, error) {
97
120
}
98
121
err := client .Call ("Solver.RootFactors" , args , & result )
99
122
if err != nil {
123
+ if exitErr := checkExit (); exitErr != nil {
124
+ err = exitErr
125
+ }
100
126
return nil , nil , err
101
127
}
102
128
return result .Roots , result .Exponents , nil
@@ -114,6 +140,10 @@ func Roots(a []*big.Int, F *big.Int) ([]*big.Int, error) {
114
140
return nil , err
115
141
}
116
142
143
+ if err := checkExit (); err != nil {
144
+ return nil , err
145
+ }
146
+
117
147
var args struct {
118
148
A []* big.Int
119
149
F * big.Int
@@ -126,6 +156,9 @@ func Roots(a []*big.Int, F *big.Int) ([]*big.Int, error) {
126
156
}
127
157
err := client .Call ("Solver.Roots" , args , & result )
128
158
if err != nil {
159
+ if exitErr := checkExit (); exitErr != nil {
160
+ err = exitErr
161
+ }
129
162
return nil , err
130
163
}
131
164
if result .RepeatedRoot != nil {
0 commit comments