hyperhq / runv

Hypervisor-based Runtime for OCI
Apache License 2.0
828 stars 129 forks source link

check close before send delay command to hyperstart chan #482

Closed gnawux closed 7 years ago

gnawux commented 7 years ago

see http://ci.hypercontainer.io:8080/job/hyperd-auto/330/consoleFull

Signed-off-by: Wang Xu gnawux@gmail.com

gnawux commented 7 years ago

however, I am not sure should I consider the chan might block at some case.

laijs commented 7 years ago

however, I am not sure should I consider the chan might block at some case.

it is a possible, and cause deadlock. it seems defer + recovery() proper.

gnawux commented 7 years ago

I don't like the taste of recover().... ok, it's a rare case....

laijs commented 7 years ago

one of the ways to avoid the deadlock, but I don't like it either.

diff --git a/hyperstart/libhyperstart/json.go b/hyperstart/libhyperstart/json.go
index 852a690..76ffbf0 100644
--- a/hyperstart/libhyperstart/json.go
+++ b/hyperstart/libhyperstart/json.go
@@ -82,6 +82,13 @@ func (h *jsonBasedHyperstart) Log(level hlog.LogLevel, args ...interface{}) {
 }

 func (h *jsonBasedHyperstart) Close() {
+       go func() {
+               for cmd := range h.ctlChan {
+                       if cmd.Code != hyperstartapi.INIT_ACK && cmd.Code != hyperstartapi.INIT_ERROR {
+                               cmd.result <- fmt.Errorf("hyperstart closed")
+                       }
+               }
+       }()
        h.Lock()
        defer h.Unlock()
        if !h.closed {
@@ -97,11 +104,6 @@ func (h *jsonBasedHyperstart) Close() {
                close(h.ctlChan)
                close(h.streamChan)
                close(h.processAsyncEvents)
-               for cmd := range h.ctlChan {
-                       if cmd.Code != hyperstartapi.INIT_ACK && cmd.Code != hyperstartapi.INIT_ERROR {
-                               cmd.result <- fmt.Errorf("hyperstart closed")
-                       }
-               }
                h.closed = true
        }
 }
gnawux commented 7 years ago

@laijs I think you could close this and push a new PR

gnawux commented 7 years ago

@laijs updated

gnawux commented 7 years ago

I am considering should I use recover to avoid a lock in a hot path

h.ctlChan <- &hyperstartCmd{Code: res.Code, retMsg: res.Message}
laijs commented 7 years ago

it seams better to avoid the lock in handleMsgFromHyperstart()

gnawux commented 7 years ago

ok, same idea. I will use the ugly recover instead.

gnawux commented 7 years ago

updated again, with recover instead of lock