From d6fd0d40184601f8f1ba9c9c7a57620b2c8cfb9f Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 29 Mar 2021 13:50:29 +0200 Subject: [PATCH 1/4] Add Flag util --- utils/flag.go | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 utils/flag.go diff --git a/utils/flag.go b/utils/flag.go new file mode 100644 index 0000000..42e7aa3 --- /dev/null +++ b/utils/flag.go @@ -0,0 +1,84 @@ +package utils + +import ( + "sync" + + "github.com/tevino/abool" +) + +// FlagController is a simple system to broadcast a flag value. +type FlagController struct { + flag *abool.AtomicBool + signal chan struct{} + lock sync.Mutex +} + +// Flag receives changes from its FlagController. +// A Flag must only be used in one goroutine and is not concurrency safe, +// but fast. +type Flag struct { + flag *abool.AtomicBool + signal chan struct{} + controller *FlagController +} + +// NewFlagController returns a new FlagController. +// In the initial state, the flag is not set and the singal does not trigger. +func NewFlagController() *FlagController { + return &FlagController{ + flag: abool.New(), + signal: make(chan struct{}), + lock: sync.Mutex{}, + } +} + +// NewFlag returns a new Flag controlled by this controller. +// In the initial state, the flag is set and the singal triggers. +// You can call Refresh immediately to get the current state from the +// controller. +func (cfc *FlagController) NewFlag() *Flag { + newFlag := &Flag{ + flag: abool.NewBool(true), + signal: make(chan struct{}), + controller: cfc, + } + close(newFlag.signal) + return newFlag +} + +// NotifyAndReset notifies all flags of this controller and resets the +// controller state. +func (cfc *FlagController) NotifyAndReset() { + cfc.lock.Lock() + defer cfc.lock.Unlock() + + // Notify all flags of the change. + cfc.flag.Set() + close(cfc.signal) + + // Reset + cfc.flag = abool.New() + cfc.signal = make(chan struct{}) +} + +// Signal returns a channel that waits for the flag to be set. This does not +// reset the Flag itself, you'll need to call Refresh for that. +func (cf *Flag) Signal() <-chan struct{} { + return cf.signal +} + +// IsSet returns whether the flag was set since the last Refresh. +// This does not reset the Flag itself, you'll need to call Refresh for that. +func (cf *Flag) IsSet() bool { + return cf.flag.IsSet() +} + +// Refresh fetches the current state from the controller. +func (cf *Flag) Refresh() { + cf.controller.lock.Lock() + defer cf.controller.lock.Unlock() + + // Copy current flag and signal from the controller. + cf.flag = cf.controller.flag + cf.signal = cf.controller.signal +} From 0d6ed345202873a5d33b4fee7a309c00e1487692 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 29 Mar 2021 13:50:50 +0200 Subject: [PATCH 2/4] Improve powershell flags --- utils/osdetail/powershell_windows.go | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/osdetail/powershell_windows.go b/utils/osdetail/powershell_windows.go index 7478abb..52ce5c4 100644 --- a/utils/osdetail/powershell_windows.go +++ b/utils/osdetail/powershell_windows.go @@ -12,6 +12,7 @@ func RunPowershellCmd(script string) (output string, err error) { // Create command to execute. cmd := exec.Command( "powershell.exe", + "-ExecutionPolicy", "Bypass", "-NoProfile", "-NonInteractive", "[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n"+script, From 2b07a6900e1ca969a45b01458972af2c27528b96 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Apr 2021 14:14:26 +0200 Subject: [PATCH 3/4] Rename FlagController to BroadcastFlag --- utils/flag.go | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/utils/flag.go b/utils/flag.go index 42e7aa3..51c79f2 100644 --- a/utils/flag.go +++ b/utils/flag.go @@ -6,79 +6,79 @@ import ( "github.com/tevino/abool" ) -// FlagController is a simple system to broadcast a flag value. -type FlagController struct { +// BroadcastFlag is a simple system to broadcast a flag value. +type BroadcastFlag struct { flag *abool.AtomicBool signal chan struct{} lock sync.Mutex } -// Flag receives changes from its FlagController. +// Flag receives changes from its broadcasting flag. // A Flag must only be used in one goroutine and is not concurrency safe, // but fast. type Flag struct { - flag *abool.AtomicBool - signal chan struct{} - controller *FlagController + flag *abool.AtomicBool + signal chan struct{} + broadcaster *BroadcastFlag } -// NewFlagController returns a new FlagController. +// NewBroadcastFlag returns a new BroadcastFlag. // In the initial state, the flag is not set and the singal does not trigger. -func NewFlagController() *FlagController { - return &FlagController{ +func NewBroadcastFlag() *BroadcastFlag { + return &BroadcastFlag{ flag: abool.New(), signal: make(chan struct{}), lock: sync.Mutex{}, } } -// NewFlag returns a new Flag controlled by this controller. +// NewFlag returns a new Flag that listens to this broadcasting flag. // In the initial state, the flag is set and the singal triggers. // You can call Refresh immediately to get the current state from the -// controller. -func (cfc *FlagController) NewFlag() *Flag { +// broadcasting flag. +func (bf *BroadcastFlag) NewFlag() *Flag { newFlag := &Flag{ - flag: abool.NewBool(true), - signal: make(chan struct{}), - controller: cfc, + flag: abool.NewBool(true), + signal: make(chan struct{}), + broadcaster: bf, } close(newFlag.signal) return newFlag } -// NotifyAndReset notifies all flags of this controller and resets the -// controller state. -func (cfc *FlagController) NotifyAndReset() { - cfc.lock.Lock() - defer cfc.lock.Unlock() +// NotifyAndReset notifies all flags of this broadcasting flag and resets the +// internal broadcast flag state. +func (bf *BroadcastFlag) NotifyAndReset() { + bf.lock.Lock() + defer bf.lock.Unlock() // Notify all flags of the change. - cfc.flag.Set() - close(cfc.signal) + bf.flag.Set() + close(bf.signal) // Reset - cfc.flag = abool.New() - cfc.signal = make(chan struct{}) + bf.flag = abool.New() + bf.signal = make(chan struct{}) } // Signal returns a channel that waits for the flag to be set. This does not // reset the Flag itself, you'll need to call Refresh for that. -func (cf *Flag) Signal() <-chan struct{} { - return cf.signal +func (f *Flag) Signal() <-chan struct{} { + return f.signal } // IsSet returns whether the flag was set since the last Refresh. // This does not reset the Flag itself, you'll need to call Refresh for that. -func (cf *Flag) IsSet() bool { - return cf.flag.IsSet() +func (f *Flag) IsSet() bool { + return f.flag.IsSet() } -// Refresh fetches the current state from the controller. -func (cf *Flag) Refresh() { - cf.controller.lock.Lock() - defer cf.controller.lock.Unlock() +// Refresh fetches the current state from the broadcasting flag. +func (f *Flag) Refresh() { + f.broadcaster.lock.Lock() + defer f.broadcaster.lock.Unlock() - // Copy current flag and signal from the controller. - cf.flag = cf.controller.flag - cf.signal = cf.controller.signal + // Copy current flag and signal from the broadcasting flag. + f.flag = f.broadcaster.flag + f.signal = f.broadcaster.signal } From 7be481362de2bacc9436d6165e908c00b74df451 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Apr 2021 14:14:59 +0200 Subject: [PATCH 4/4] Rename file --- utils/{flag.go => broadcastflag.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename utils/{flag.go => broadcastflag.go} (100%) diff --git a/utils/flag.go b/utils/broadcastflag.go similarity index 100% rename from utils/flag.go rename to utils/broadcastflag.go