diff --git a/pgraph/pgraph.go b/pgraph/pgraph.go index adacc5d9..2d2b945b 100644 --- a/pgraph/pgraph.go +++ b/pgraph/pgraph.go @@ -29,17 +29,6 @@ import ( errwrap "github.com/pkg/errors" ) -//go:generate stringer -type=graphState -output=graphstate_stringer.go -type graphState int - -const ( - graphStateNil graphState = iota - graphStateStarting - graphStateStarted - graphStatePausing - graphStatePaused -) - // Graph is the graph structure in this library. // The graph abstract data type (ADT) is defined as follows: // * the directed graph arrows point from left to right ( -> ) @@ -53,9 +42,7 @@ type Graph struct { kv map[string]interface{} // some values associated with the graph // legacy - state graphState - fastPause bool // used to disable pokes for a fast pause - mutex *sync.Mutex // used when modifying graph State variable + fastPause bool // used to disable pokes for a fast pause wg *sync.WaitGroup } @@ -83,9 +70,7 @@ func (g *Graph) Init() error { g.kv = make(map[string]interface{}) // legacy - g.state = graphStateNil // ptr b/c: Mutex/WaitGroup must not be copied after first use - g.mutex = &sync.Mutex{} g.wg = &sync.WaitGroup{} return nil } @@ -144,8 +129,6 @@ func (g *Graph) Copy() *Graph { kv: g.kv, // legacy - state: g.state, - mutex: g.mutex, wg: g.wg, fastPause: g.fastPause, } @@ -165,24 +148,6 @@ func (g *Graph) SetName(name string) { g.Name = name } -// getState returns the state of the graph. This state is used for optimizing -// certain algorithms by knowing what part of processing the graph is currently -// undergoing. -func (g *Graph) getState() graphState { - //g.mutex.Lock() - //defer g.mutex.Unlock() - return g.state -} - -// setState sets the graph state and returns the previous state. -func (g *Graph) setState(state graphState) graphState { - g.mutex.Lock() - defer g.mutex.Unlock() - prev := g.getState() - g.state = state - return prev -} - // AddVertex uses variadic input to add all listed vertices to the graph func (g *Graph) AddVertex(xv ...*Vertex) { for _, v := range xv { diff --git a/resources/pgraph.go b/resources/pgraph.go new file mode 100644 index 00000000..99142ad4 --- /dev/null +++ b/resources/pgraph.go @@ -0,0 +1,75 @@ +// Mgmt +// Copyright (C) 2013-2017+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package resources + +import ( + "fmt" + "log" + + "github.com/purpleidea/mgmt/pgraph" +) + +//go:generate stringer -type=graphState -output=graphstate_stringer.go +type graphState uint + +const ( + graphStateNil graphState = iota + graphStateStarting + graphStateStarted + graphStatePausing + graphStatePaused +) + +// getState returns the state of the graph. This state is used for optimizing +// certain algorithms by knowing what part of processing the graph is currently +// undergoing. +func getState(g *pgraph.Graph) graphState { + //mutex := StateLockFromGraph(g) + //mutex.Lock() + //defer mutex.Unlock() + if u, ok := g.Value("state"); ok { + return util.Uint(u) + } + return graphStateNil +} + +// setState sets the graph state and returns the previous state. +func setState(g *pgraph.Graph, state graphState) graphState { + mutex := StateLockFromGraph(g) + mutex.Lock() + defer mutex.Unlock() + prev := getState(g) + g.SetValue("state", state) + return prev +} + +// StateLockFromGraph returns a pointer to the state lock stored with the graph, +// otherwise it panics. If one does not exist, it will create it. +func StateLockFromGraph(g *pgraph.Graph) *sync.Mutex { + x, exists := g.Value("mutex") + if !exists { + g.SetValue("mutex", &sync.Mutex{}) + x, _ = g.Value("mutex") + } + + m, ok := x.(*sync.Mutex) + if !ok { + panic("not a *sync.Mutex") + } + return m +} diff --git a/util/interfaces.go b/util/interfaces.go index 9f96c7c2..16b74f7c 100644 --- a/util/interfaces.go +++ b/util/interfaces.go @@ -25,3 +25,12 @@ func Bool(x interface{}) bool { } return b } + +// Uint returns the interface value if it is a uint, and otherwise it panics. +func Uint(x interface{}) uint { + u, ok := x.(uint) + if !ok { + panic("not a uint") + } + return u +}