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
|
ptyMaster io.Closer
|
||||||
|
|
||||||
runtime *Runtime
|
runtime *Runtime
|
||||||
|
|
||||||
|
waitLock chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -406,6 +408,10 @@ func (container *Container) Start() error {
|
||||||
// FIXME: save state on disk *first*, then converge
|
// FIXME: save state on disk *first*, then converge
|
||||||
// this way disk state is used as a journal, eg. we can restore after crash etc.
|
// this way disk state is used as a journal, eg. we can restore after crash etc.
|
||||||
container.State.setRunning(container.cmd.Process.Pid)
|
container.State.setRunning(container.cmd.Process.Pid)
|
||||||
|
|
||||||
|
// Init the lock
|
||||||
|
container.waitLock = make(chan struct{})
|
||||||
|
|
||||||
container.ToDisk()
|
container.ToDisk()
|
||||||
go container.monitor()
|
go container.monitor()
|
||||||
return nil
|
return nil
|
||||||
|
@ -522,6 +528,10 @@ func (container *Container) monitor() {
|
||||||
|
|
||||||
// Report status back
|
// Report status back
|
||||||
container.State.setStopped(exitCode)
|
container.State.setStopped(exitCode)
|
||||||
|
|
||||||
|
// Release the lock
|
||||||
|
close(container.waitLock)
|
||||||
|
|
||||||
if err := container.ToDisk(); err != nil {
|
if err := container.ToDisk(); err != nil {
|
||||||
// FIXME: there is a race condition here which causes this to fail during the unit tests.
|
// 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
|
// 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.
|
// Wait blocks until the container stops running, then returns its exit code.
|
||||||
func (container *Container) Wait() int {
|
func (container *Container) Wait() int {
|
||||||
|
<-container.waitLock
|
||||||
for container.State.Running {
|
|
||||||
container.State.wait()
|
|
||||||
}
|
|
||||||
return container.State.ExitCode
|
return container.State.ExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,6 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
|
||||||
if err := container.FromDisk(); err != nil {
|
if err := container.FromDisk(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
container.State.initLock()
|
|
||||||
if container.Id != id {
|
if container.Id != id {
|
||||||
return container, fmt.Errorf("Container %s is stored at %s", 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?
|
// 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 the container is supposed to be running, make sure of it
|
||||||
if container.State.Running {
|
if container.State.Running {
|
||||||
if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
|
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
|
container.runtime = runtime
|
||||||
// Setup state lock (formerly in newState()
|
|
||||||
container.State.initLock()
|
|
||||||
// Attach to stdout and stderr
|
// Attach to stdout and stderr
|
||||||
container.stderr = newWriteBroadcaster()
|
container.stderr = newWriteBroadcaster()
|
||||||
container.stdout = newWriteBroadcaster()
|
container.stdout = newWriteBroadcaster()
|
||||||
|
|
25
state.go
25
state.go
|
@ -2,7 +2,6 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,9 +10,6 @@ type State struct {
|
||||||
Pid int
|
Pid int
|
||||||
ExitCode int
|
ExitCode int
|
||||||
StartedAt time.Time
|
StartedAt time.Time
|
||||||
|
|
||||||
stateChangeLock *sync.Mutex
|
|
||||||
stateChangeCond *sync.Cond
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a human-readable description of the state
|
// String returns a human-readable description of the state
|
||||||
|
@ -29,31 +25,10 @@ func (s *State) setRunning(pid int) {
|
||||||
s.ExitCode = 0
|
s.ExitCode = 0
|
||||||
s.Pid = pid
|
s.Pid = pid
|
||||||
s.StartedAt = time.Now()
|
s.StartedAt = time.Now()
|
||||||
s.broadcast()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) setStopped(exitCode int) {
|
func (s *State) setStopped(exitCode int) {
|
||||||
s.Running = false
|
s.Running = false
|
||||||
s.Pid = 0
|
s.Pid = 0
|
||||||
s.ExitCode = exitCode
|
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