mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Remove the mutexes and use chan instead in order to handle the wait lock
This commit is contained in:
parent
0767916ade
commit
329f4449dc
3 changed files with 13 additions and 32 deletions
15
container.go
15
container.go
|
@ -43,6 +43,8 @@ type Container struct {
|
|||
ptyMaster io.Closer
|
||||
|
||||
runtime *Runtime
|
||||
|
||||
waitLock chan struct{}
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
@ -406,6 +408,10 @@ func (container *Container) Start() error {
|
|||
// FIXME: save state on disk *first*, then converge
|
||||
// this way disk state is used as a journal, eg. we can restore after crash etc.
|
||||
container.State.setRunning(container.cmd.Process.Pid)
|
||||
|
||||
// Init the lock
|
||||
container.waitLock = make(chan struct{})
|
||||
|
||||
container.ToDisk()
|
||||
go container.monitor()
|
||||
return nil
|
||||
|
@ -522,6 +528,10 @@ func (container *Container) monitor() {
|
|||
|
||||
// Report status back
|
||||
container.State.setStopped(exitCode)
|
||||
|
||||
// Release the lock
|
||||
close(container.waitLock)
|
||||
|
||||
if err := container.ToDisk(); err != nil {
|
||||
// FIXME: there is a race condition here which causes this to fail during the unit tests.
|
||||
// If another goroutine was waiting for Wait() to return before removing the container's root
|
||||
|
@ -588,10 +598,7 @@ func (container *Container) Restart() error {
|
|||
|
||||
// Wait blocks until the container stops running, then returns its exit code.
|
||||
func (container *Container) Wait() int {
|
||||
|
||||
for container.State.Running {
|
||||
container.State.wait()
|
||||
}
|
||||
<-container.waitLock
|
||||
return container.State.ExitCode
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,6 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
|
|||
if err := container.FromDisk(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
container.State.initLock()
|
||||
if container.Id != id {
|
||||
return container, fmt.Errorf("Container %s is stored at %s", container.Id, id)
|
||||
}
|
||||
|
@ -136,6 +135,7 @@ func (runtime *Runtime) Register(container *Container) error {
|
|||
}
|
||||
|
||||
// FIXME: if the container is supposed to be running but is not, auto restart it?
|
||||
// if so, then we need to restart monitor and init a new lock
|
||||
// If the container is supposed to be running, make sure of it
|
||||
if container.State.Running {
|
||||
if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
|
||||
|
@ -152,8 +152,7 @@ func (runtime *Runtime) Register(container *Container) error {
|
|||
}
|
||||
|
||||
container.runtime = runtime
|
||||
// Setup state lock (formerly in newState()
|
||||
container.State.initLock()
|
||||
|
||||
// Attach to stdout and stderr
|
||||
container.stderr = newWriteBroadcaster()
|
||||
container.stdout = newWriteBroadcaster()
|
||||
|
|
25
state.go
25
state.go
|
@ -2,7 +2,6 @@ package docker
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -11,9 +10,6 @@ type State struct {
|
|||
Pid int
|
||||
ExitCode int
|
||||
StartedAt time.Time
|
||||
|
||||
stateChangeLock *sync.Mutex
|
||||
stateChangeCond *sync.Cond
|
||||
}
|
||||
|
||||
// String returns a human-readable description of the state
|
||||
|
@ -29,31 +25,10 @@ func (s *State) setRunning(pid int) {
|
|||
s.ExitCode = 0
|
||||
s.Pid = pid
|
||||
s.StartedAt = time.Now()
|
||||
s.broadcast()
|
||||
}
|
||||
|
||||
func (s *State) setStopped(exitCode int) {
|
||||
s.Running = false
|
||||
s.Pid = 0
|
||||
s.ExitCode = exitCode
|
||||
s.broadcast()
|
||||
}
|
||||
|
||||
func (s *State) initLock() {
|
||||
if s.stateChangeLock == nil {
|
||||
s.stateChangeLock = &sync.Mutex{}
|
||||
s.stateChangeCond = sync.NewCond(s.stateChangeLock)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) broadcast() {
|
||||
s.stateChangeLock.Lock()
|
||||
s.stateChangeCond.Broadcast()
|
||||
s.stateChangeLock.Unlock()
|
||||
}
|
||||
|
||||
func (s *State) wait() {
|
||||
s.stateChangeLock.Lock()
|
||||
s.stateChangeCond.Wait()
|
||||
s.stateChangeLock.Unlock()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue