Skip to content

Commit

Permalink
Add RW lock to Winlogbeat checkpoint (#8007)
Browse files Browse the repository at this point in the history
During testing it was possible for two goroutines to be reading and writing
to the checkpoint file. This change adds a RWMutex that guards against
the persist() method and the read() method from stepping on each other.

Fixes #7897
  • Loading branch information
andrewkroh authored and ruflin committed Aug 22, 2018
1 parent 7a0dc61 commit be71c60
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions winlogbeat/checkpoint/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Checkpoint struct {
done chan struct{} // Channel for shutting down the checkpoint worker.
once sync.Once // Used to guarantee shutdown happens once.
file string // File where the state is persisted.
fileLock sync.RWMutex // Lock that protects concurrent reads/writes to file.
numUpdates int // Number of updates received since last persisting to disk.
maxUpdates int // Maximum number of updates to buffer before persisting to disk.
flushInterval time.Duration // Maximum time interval that can pass before persisting to disk.
Expand Down Expand Up @@ -208,6 +209,9 @@ func (c *Checkpoint) persist() bool {

// flush writes the current state to disk.
func (c *Checkpoint) flush() error {
c.fileLock.Lock()
defer c.fileLock.Unlock()

tempFile := c.file + ".new"
file, err := create(tempFile)
if os.IsNotExist(err) {
Expand Down Expand Up @@ -258,6 +262,9 @@ func (c *Checkpoint) flush() error {
// read loads the persisted state from disk. If the file does not exists then
// the method returns nil and no error.
func (c *Checkpoint) read() (*PersistedState, error) {
c.fileLock.RLock()
defer c.fileLock.RUnlock()

contents, err := ioutil.ReadFile(c.file)
if err != nil {
if os.IsNotExist(err) {
Expand Down

0 comments on commit be71c60

Please sign in to comment.