diff --git a/pkg/store/container/container.go b/pkg/store/container/container.go index cbac43257..76cf41a7a 100644 --- a/pkg/store/container/container.go +++ b/pkg/store/container/container.go @@ -39,7 +39,7 @@ type Container struct { // Container IO IO *cio.ContainerIO // StopCh is used to propagate the stop information of the container. - store.StopCh + *store.StopCh } // Opts sets specific information to newly created Container. @@ -80,7 +80,7 @@ func WithStatus(status Status, root string) Opts { func NewContainer(metadata Metadata, opts ...Opts) (Container, error) { c := Container{ Metadata: metadata, - StopCh: store.StopCh(make(chan struct{})), + StopCh: store.NewStopCh(), } for _, o := range opts { if err := o(&c); err != nil { diff --git a/pkg/store/sandbox/sandbox.go b/pkg/store/sandbox/sandbox.go index dfcc7dde0..f9c45ef08 100644 --- a/pkg/store/sandbox/sandbox.go +++ b/pkg/store/sandbox/sandbox.go @@ -37,7 +37,7 @@ type Sandbox struct { // CNI network namespace client NetNS *NetNS // StopCh is used to propagate the stop information of the sandbox. - store.StopCh + *store.StopCh } // NewSandbox creates an internally used sandbox type. This functions reminds @@ -46,7 +46,7 @@ func NewSandbox(metadata Metadata, status Status) Sandbox { s := Sandbox{ Metadata: metadata, Status: StoreStatus(status), - StopCh: store.StopCh(make(chan struct{})), + StopCh: store.NewStopCh(), } if status.State == StateNotReady { s.Stop() diff --git a/pkg/store/util.go b/pkg/store/util.go index 8a7b6fcf9..8ea173e0d 100644 --- a/pkg/store/util.go +++ b/pkg/store/util.go @@ -16,15 +16,35 @@ limitations under the License. package store +import "sync" + // StopCh is used to propagate the stop information of a container. -type StopCh chan struct{} +type StopCh struct { + mu sync.Mutex + ch chan struct{} + closed bool +} + +// NewStopCh creates a stop channel. The channel is open by default. +func NewStopCh() *StopCh { + return &StopCh{ + ch: make(chan struct{}), + closed: false, + } +} // Stop close stopCh of the container. -func (ch StopCh) Stop() { - close(ch) +func (s *StopCh) Stop() { + s.mu.Lock() + defer s.mu.Unlock() + if s.closed { + return + } + close(s.ch) + s.closed = true } // Stopped return the stopCh of the container as a readonly channel. -func (ch StopCh) Stopped() <-chan struct{} { - return ch +func (s *StopCh) Stopped() <-chan struct{} { + return s.ch }