fix data race

This commit is contained in:
miraclesu 2015-12-24 16:47:46 +08:00
parent 2bc904e34f
commit 274567a526
4 changed files with 26 additions and 16 deletions

12
tail.go
View File

@ -10,6 +10,7 @@ import (
"log"
"os"
"strings"
"sync"
"time"
"github.com/hpcloud/tail/ratelimiter"
@ -82,6 +83,8 @@ type Tail struct {
changes *watch.FileChanges
tomb.Tomb // provides: Done, Kill, Dying
lk sync.Mutex
}
var (
@ -140,7 +143,9 @@ func (tail *Tail) Tell() (offset int64, err error) {
}
offset, err = tail.file.Seek(0, os.SEEK_CUR)
if err == nil {
tail.lk.Lock()
offset -= int64(tail.reader.Buffered())
tail.lk.Unlock()
}
return
}
@ -187,7 +192,9 @@ func (tail *Tail) reopen() error {
}
func (tail *Tail) readLine() (string, error) {
tail.lk.Lock()
line, err := tail.reader.ReadString('\n')
tail.lk.Unlock()
if err != nil {
// Note ReadString "returns the data read before the error" in
// case of an error, including EOF, so we return it as is. The
@ -315,7 +322,10 @@ func (tail *Tail) waitForChanges() error {
if err != nil {
return err
}
tail.changes = tail.watcher.ChangeEvents(&tail.Tomb, pos)
tail.changes, err = tail.watcher.ChangeEvents(&tail.Tomb, pos)
if err != nil {
return err
}
}
select {

View File

@ -55,14 +55,13 @@ func (fw *InotifyFileWatcher) BlockUntilExists(t *tomb.Tomb) error {
panic("unreachable")
}
func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) *FileChanges {
changes := NewFileChanges()
func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChanges, error) {
err := Watch(fw.Filename)
if err != nil {
go changes.NotifyDeleted()
return nil, err
}
changes := NewFileChanges()
fw.Size = pos
go func() {
@ -116,5 +115,5 @@ func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) *FileChanges
}
}()
return changes
return changes, nil
}

View File

@ -3,11 +3,12 @@
package watch
import (
"github.com/hpcloud/tail/util"
"gopkg.in/tomb.v1"
"os"
"runtime"
"time"
"github.com/hpcloud/tail/util"
"gopkg.in/tomb.v1"
)
// PollingFileWatcher polls the file for changes.
@ -40,7 +41,12 @@ func (fw *PollingFileWatcher) BlockUntilExists(t *tomb.Tomb) error {
panic("unreachable")
}
func (fw *PollingFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) *FileChanges {
func (fw *PollingFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChanges, error) {
origFi, err := os.Stat(fw.Filename)
if err != nil {
return nil, err
}
changes := NewFileChanges()
var prevModTime time.Time
@ -48,11 +54,6 @@ func (fw *PollingFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) *FileChanges
// the fatal (below) with tomb's Kill.
fw.Size = pos
origFi, err := os.Stat(fw.Filename)
if err != nil {
changes.NotifyDeleted()
return changes
}
go func() {
defer changes.Close()
@ -110,7 +111,7 @@ func (fw *PollingFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) *FileChanges
}
}()
return changes
return changes, nil
}
func init() {

View File

@ -15,5 +15,5 @@ type FileWatcher interface {
// or truncation event.
// In order to properly report truncations, ChangeEvents requires
// the caller to pass their current offset in the file.
ChangeEvents(*tomb.Tomb, int64) *FileChanges
ChangeEvents(*tomb.Tomb, int64) (*FileChanges, error)
}