Fix a potential panic

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-02-22 03:16:41 +00:00
parent 7f5687c801
commit f5390d01d6
3 changed files with 29 additions and 9 deletions

View File

@ -39,7 +39,7 @@ type Container struct {
// Container IO // Container IO
IO *cio.ContainerIO IO *cio.ContainerIO
// StopCh is used to propagate the stop information of the container. // StopCh is used to propagate the stop information of the container.
store.StopCh *store.StopCh
} }
// Opts sets specific information to newly created Container. // 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) { func NewContainer(metadata Metadata, opts ...Opts) (Container, error) {
c := Container{ c := Container{
Metadata: metadata, Metadata: metadata,
StopCh: store.StopCh(make(chan struct{})), StopCh: store.NewStopCh(),
} }
for _, o := range opts { for _, o := range opts {
if err := o(&c); err != nil { if err := o(&c); err != nil {

View File

@ -37,7 +37,7 @@ type Sandbox struct {
// CNI network namespace client // CNI network namespace client
NetNS *NetNS NetNS *NetNS
// StopCh is used to propagate the stop information of the sandbox. // 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 // NewSandbox creates an internally used sandbox type. This functions reminds
@ -46,7 +46,7 @@ func NewSandbox(metadata Metadata, status Status) Sandbox {
s := Sandbox{ s := Sandbox{
Metadata: metadata, Metadata: metadata,
Status: StoreStatus(status), Status: StoreStatus(status),
StopCh: store.StopCh(make(chan struct{})), StopCh: store.NewStopCh(),
} }
if status.State == StateNotReady { if status.State == StateNotReady {
s.Stop() s.Stop()

View File

@ -16,15 +16,35 @@ limitations under the License.
package store package store
import "sync"
// StopCh is used to propagate the stop information of a container. // 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. // Stop close stopCh of the container.
func (ch StopCh) Stop() { func (s *StopCh) Stop() {
close(ch) 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. // Stopped return the stopCh of the container as a readonly channel.
func (ch StopCh) Stopped() <-chan struct{} { func (s *StopCh) Stopped() <-chan struct{} {
return ch return s.ch
} }