|
@@ -1,7 +1,6 @@
|
|
|
package daemon
|
|
|
|
|
|
import (
|
|
|
- "encoding/json"
|
|
|
"fmt"
|
|
|
"sync"
|
|
|
"time"
|
|
@@ -10,7 +9,7 @@ import (
|
|
|
)
|
|
|
|
|
|
type State struct {
|
|
|
- sync.RWMutex
|
|
|
+ sync.Mutex
|
|
|
Running bool
|
|
|
Paused bool
|
|
|
Restarting bool
|
|
@@ -29,9 +28,6 @@ func NewState() *State {
|
|
|
|
|
|
// String returns a human-readable description of the state
|
|
|
func (s *State) String() string {
|
|
|
- s.RLock()
|
|
|
- defer s.RUnlock()
|
|
|
-
|
|
|
if s.Running {
|
|
|
if s.Paused {
|
|
|
return fmt.Sprintf("Up %s (Paused)", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
|
|
@@ -50,16 +46,6 @@ func (s *State) String() string {
|
|
|
return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
|
|
|
}
|
|
|
|
|
|
-type jState State
|
|
|
-
|
|
|
-// MarshalJSON for state is needed to avoid race conditions on inspect
|
|
|
-func (s *State) MarshalJSON() ([]byte, error) {
|
|
|
- s.RLock()
|
|
|
- b, err := json.Marshal(jState(*s))
|
|
|
- s.RUnlock()
|
|
|
- return b, err
|
|
|
-}
|
|
|
-
|
|
|
func wait(waitChan <-chan struct{}, timeout time.Duration) error {
|
|
|
if timeout < 0 {
|
|
|
<-waitChan
|
|
@@ -77,14 +63,14 @@ func wait(waitChan <-chan struct{}, timeout time.Duration) error {
|
|
|
// immediatly. If you want wait forever you must supply negative timeout.
|
|
|
// Returns pid, that was passed to SetRunning
|
|
|
func (s *State) WaitRunning(timeout time.Duration) (int, error) {
|
|
|
- s.RLock()
|
|
|
- if s.IsRunning() {
|
|
|
+ s.Lock()
|
|
|
+ if s.Running {
|
|
|
pid := s.Pid
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return pid, nil
|
|
|
}
|
|
|
waitChan := s.waitChan
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
if err := wait(waitChan, timeout); err != nil {
|
|
|
return -1, err
|
|
|
}
|
|
@@ -95,14 +81,14 @@ func (s *State) WaitRunning(timeout time.Duration) (int, error) {
|
|
|
// immediatly. If you want wait forever you must supply negative timeout.
|
|
|
// Returns exit code, that was passed to SetStopped
|
|
|
func (s *State) WaitStop(timeout time.Duration) (int, error) {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
if !s.Running {
|
|
|
exitCode := s.ExitCode
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return exitCode, nil
|
|
|
}
|
|
|
waitChan := s.waitChan
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
if err := wait(waitChan, timeout); err != nil {
|
|
|
return -1, err
|
|
|
}
|
|
@@ -110,28 +96,33 @@ func (s *State) WaitStop(timeout time.Duration) (int, error) {
|
|
|
}
|
|
|
|
|
|
func (s *State) IsRunning() bool {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
res := s.Running
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return res
|
|
|
}
|
|
|
|
|
|
func (s *State) GetPid() int {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
res := s.Pid
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return res
|
|
|
}
|
|
|
|
|
|
func (s *State) GetExitCode() int {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
res := s.ExitCode
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return res
|
|
|
}
|
|
|
|
|
|
func (s *State) SetRunning(pid int) {
|
|
|
s.Lock()
|
|
|
+ s.setRunning(pid)
|
|
|
+ s.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+func (s *State) setRunning(pid int) {
|
|
|
s.Running = true
|
|
|
s.Paused = false
|
|
|
s.Restarting = false
|
|
@@ -140,11 +131,15 @@ func (s *State) SetRunning(pid int) {
|
|
|
s.StartedAt = time.Now().UTC()
|
|
|
close(s.waitChan) // fire waiters for start
|
|
|
s.waitChan = make(chan struct{})
|
|
|
- s.Unlock()
|
|
|
}
|
|
|
|
|
|
func (s *State) SetStopped(exitCode int) {
|
|
|
s.Lock()
|
|
|
+ s.setStopped(exitCode)
|
|
|
+ s.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+func (s *State) setStopped(exitCode int) {
|
|
|
s.Running = false
|
|
|
s.Restarting = false
|
|
|
s.Pid = 0
|
|
@@ -152,7 +147,6 @@ func (s *State) SetStopped(exitCode int) {
|
|
|
s.ExitCode = exitCode
|
|
|
close(s.waitChan) // fire waiters for stop
|
|
|
s.waitChan = make(chan struct{})
|
|
|
- s.Unlock()
|
|
|
}
|
|
|
|
|
|
// SetRestarting is when docker hanldes the auto restart of containers when they are
|
|
@@ -172,9 +166,9 @@ func (s *State) SetRestarting(exitCode int) {
|
|
|
}
|
|
|
|
|
|
func (s *State) IsRestarting() bool {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
res := s.Restarting
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return res
|
|
|
}
|
|
|
|
|
@@ -191,8 +185,8 @@ func (s *State) SetUnpaused() {
|
|
|
}
|
|
|
|
|
|
func (s *State) IsPaused() bool {
|
|
|
- s.RLock()
|
|
|
+ s.Lock()
|
|
|
res := s.Paused
|
|
|
- s.RUnlock()
|
|
|
+ s.Unlock()
|
|
|
return res
|
|
|
}
|