()
| 1148 | } |
| 1149 | |
| 1150 | func (e *userspaceEngine) RequestStatus() { |
| 1151 | // This is slightly tricky. e.getStatus() can theoretically get |
| 1152 | // blocked inside wireguard for a while, and RequestStatus() is |
| 1153 | // sometimes called from a goroutine, so we don't want a lot of |
| 1154 | // them hanging around. On the other hand, requesting multiple |
| 1155 | // status updates simultaneously is pointless anyway; they will |
| 1156 | // all say the same thing. |
| 1157 | |
| 1158 | // Enqueue at most one request. If one is in progress already, this |
| 1159 | // adds one more to the queue. If one has been requested but not |
| 1160 | // started, it is a no-op. |
| 1161 | select { |
| 1162 | case e.reqCh <- struct{}{}: |
| 1163 | default: |
| 1164 | } |
| 1165 | |
| 1166 | // Dequeue at most one request. Another thread may have already |
| 1167 | // dequeued the request we enqueued above, which is fine, since the |
| 1168 | // information is guaranteed to be at least as recent as the current |
| 1169 | // call to RequestStatus(). |
| 1170 | select { |
| 1171 | case <-e.reqCh: |
| 1172 | s, err := e.getStatus() |
| 1173 | if s == nil && err == nil { |
| 1174 | e.logf("[unexpected] RequestStatus: both s and err are nil") |
| 1175 | return |
| 1176 | } |
| 1177 | if cb := e.getStatusCallback(); cb != nil { |
| 1178 | cb(s, err) |
| 1179 | } |
| 1180 | default: |
| 1181 | } |
| 1182 | } |
| 1183 | |
| 1184 | func (e *userspaceEngine) Close() { |
| 1185 | e.eventClient.Close() |
no test coverage detected