Goroutine-safe daemon.containers
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)
This commit is contained in:
parent
64bd6a6a53
commit
af17b01ad7
1 changed files with 42 additions and 29 deletions
|
@ -1,7 +1,6 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -48,10 +47,43 @@ var (
|
|||
validContainerNamePattern = regexp.MustCompile(`^/?` + validContainerNameChars + `+$`)
|
||||
)
|
||||
|
||||
type contStore struct {
|
||||
s map[string]*Container
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (c *contStore) Add(id string, cont *Container) {
|
||||
c.Lock()
|
||||
c.s[id] = cont
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
func (c *contStore) Get(id string) *Container {
|
||||
c.Lock()
|
||||
res := c.s[id]
|
||||
c.Unlock()
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *contStore) Delete(id string) {
|
||||
c.Lock()
|
||||
delete(c.s, id)
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
func (c *contStore) List() []*Container {
|
||||
containers := new(History)
|
||||
for _, cont := range c.s {
|
||||
containers.Add(cont)
|
||||
}
|
||||
containers.Sort()
|
||||
return *containers
|
||||
}
|
||||
|
||||
type Daemon struct {
|
||||
repository string
|
||||
sysInitPath string
|
||||
containers *list.List
|
||||
containers *contStore
|
||||
graph *graph.Graph
|
||||
repositories *graph.TagStore
|
||||
idIndex *utils.TruncIndex
|
||||
|
@ -87,22 +119,7 @@ func remountPrivate(mountPoint string) error {
|
|||
|
||||
// List returns an array of all containers registered in the daemon.
|
||||
func (daemon *Daemon) List() []*Container {
|
||||
containers := new(History)
|
||||
for e := daemon.containers.Front(); e != nil; e = e.Next() {
|
||||
containers.Add(e.Value.(*Container))
|
||||
}
|
||||
containers.Sort()
|
||||
return *containers
|
||||
}
|
||||
|
||||
func (daemon *Daemon) getContainerElement(id string) *list.Element {
|
||||
for e := daemon.containers.Front(); e != nil; e = e.Next() {
|
||||
container := e.Value.(*Container)
|
||||
if container.ID == id {
|
||||
return e
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return daemon.containers.List()
|
||||
}
|
||||
|
||||
// Get looks for a container by the specified ID or name, and returns it.
|
||||
|
@ -117,11 +134,7 @@ func (daemon *Daemon) Get(name string) *Container {
|
|||
return nil
|
||||
}
|
||||
|
||||
e := daemon.getContainerElement(id)
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Value.(*Container)
|
||||
return daemon.containers.Get(id)
|
||||
}
|
||||
|
||||
// Exists returns a true if a container of the specified ID or name exists,
|
||||
|
@ -177,7 +190,7 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err
|
|||
container.stdinPipe = utils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
|
||||
}
|
||||
// done
|
||||
daemon.containers.PushBack(container)
|
||||
daemon.containers.Add(container.ID, container)
|
||||
|
||||
// don't update the Suffixarray if we're starting up
|
||||
// we'll waste time if we update it for every container
|
||||
|
@ -279,7 +292,7 @@ func (daemon *Daemon) Destroy(container *Container) error {
|
|||
return fmt.Errorf("The given container is <nil>")
|
||||
}
|
||||
|
||||
element := daemon.getContainerElement(container.ID)
|
||||
element := daemon.containers.Get(container.ID)
|
||||
if element == nil {
|
||||
return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.ID)
|
||||
}
|
||||
|
@ -290,7 +303,7 @@ func (daemon *Daemon) Destroy(container *Container) error {
|
|||
|
||||
// Deregister the container before removing its directory, to avoid race conditions
|
||||
daemon.idIndex.Delete(container.ID)
|
||||
daemon.containers.Remove(element)
|
||||
daemon.containers.Delete(container.ID)
|
||||
|
||||
if _, err := daemon.containerGraph.Purge(container.ID); err != nil {
|
||||
utils.Debugf("Unable to remove container from link graph: %s", err)
|
||||
|
@ -677,11 +690,11 @@ func (daemon *Daemon) GetByName(name string) (*Container, error) {
|
|||
if entity == nil {
|
||||
return nil, fmt.Errorf("Could not find entity for %s", name)
|
||||
}
|
||||
e := daemon.getContainerElement(entity.ID())
|
||||
e := daemon.containers.Get(entity.ID())
|
||||
if e == nil {
|
||||
return nil, fmt.Errorf("Could not find container for entity id %s", entity.ID())
|
||||
}
|
||||
return e.Value.(*Container), nil
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) Children(name string) (map[string]*Container, error) {
|
||||
|
@ -860,7 +873,7 @@ func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*D
|
|||
|
||||
daemon := &Daemon{
|
||||
repository: daemonRepo,
|
||||
containers: list.New(),
|
||||
containers: &contStore{s: make(map[string]*Container)},
|
||||
graph: g,
|
||||
repositories: repositories,
|
||||
idIndex: utils.NewTruncIndex([]string{}),
|
||||
|
|
Loading…
Add table
Reference in a new issue