mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-04 20:51:44 +00:00
Remove the mutexes and use chan instead in order to handle the wait lock
This commit is contained in:
+11
-4
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user