From 3a48c061909ccbfc5c6e9ac87565752d1f21f4ea Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Fri, 14 Jul 2023 21:23:35 +0900 Subject: [PATCH 1/4] Use provided functions Changed to use lastChunkNum. --- oviewer/search.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/oviewer/search.go b/oviewer/search.go index 516518a7..ee6e1900 100644 --- a/oviewer/search.go +++ b/oviewer/search.go @@ -406,9 +406,8 @@ func (m *Document) SearchLine(ctx context.Context, searcher Searcher, lN int) (i default: } - // endChunk may be updated by Search. - endChunk := (m.BufEndNum() - 1) / ChunkSize - if cn >= endChunk { + // lastChunkNum may be updated by Search. + if cn >= m.store.lastChunkNum() { break } sn = 0 From bd4582a468a268d043d19b5b30227c8ab6603b37 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Fri, 14 Jul 2023 21:25:13 +0900 Subject: [PATCH 2/4] Changed to RWMutex --- oviewer/document.go | 2 +- oviewer/store.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/oviewer/document.go b/oviewer/document.go index 0a0c1566..6279ef70 100644 --- a/oviewer/document.go +++ b/oviewer/document.go @@ -117,7 +117,7 @@ type store struct { // chunks is the content of the file to be stored in chunks. chunks []*chunk // mu controls the mutex. - mu sync.Mutex + mu sync.RWMutex // startNum is the number of the first line that can be moved. startNum int32 diff --git a/oviewer/store.go b/oviewer/store.go index b9d831ab..0038f1d7 100644 --- a/oviewer/store.go +++ b/oviewer/store.go @@ -126,8 +126,8 @@ func (s *store) unloadChunk(chunkNum int) { // lastChunkNum returns the last chunk number. func (s *store) lastChunkNum() int { - s.mu.Lock() - defer s.mu.Unlock() + s.mu.RLock() + defer s.mu.RUnlock() return len(s.chunks) - 1 } From cd0aea02608e1440bb2bdb3b872806f0a48ce527 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Fri, 14 Jul 2023 21:26:19 +0900 Subject: [PATCH 3/4] Fixed log output position --- oviewer/reader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oviewer/reader.go b/oviewer/reader.go index 6605af69..c679b3d3 100644 --- a/oviewer/reader.go +++ b/oviewer/reader.go @@ -159,10 +159,10 @@ func (m *Document) loadChunk(reader *bufio.Reader, chunkNum int) (*bufio.Reader, start, end := m.store.chunkRange(chunkNum) if err := m.store.readLines(chunk, reader, start, end, false); err != nil { - log.Printf("Failed to read the expected number of lines(%d:%d): %s", start, end, err) if errors.Is(err, io.EOF) { return m.afterEOF(reader), nil } + log.Printf("Failed to read the expected number of lines(%d:%d): %s", start, end, err) return nil, err } return reader, nil From 9021af3f0fa2de3e1894cec786e3e973108a32f7 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Fri, 14 Jul 2023 21:26:54 +0900 Subject: [PATCH 4/4] Add comments or move to appropriate files --- main.go | 2 ++ oviewer/action.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++ oviewer/control.go | 2 +- oviewer/event.go | 52 ---------------------------------------------- oviewer/sigtstp.go | 1 + 5 files changed, 56 insertions(+), 53 deletions(-) diff --git a/main.go b/main.go index 95b81ec1..f2b1cc85 100644 --- a/main.go +++ b/main.go @@ -268,6 +268,8 @@ func flagUsage(f *pflag.FlagSet) string { return buf.String() } +// UsageFunc returns a function that returns the usage. +// This is for overwriting cobra usage. func UsageFunc() (cmd func(*cobra.Command) error) { return func(c *cobra.Command) error { fmt.Fprintf(os.Stdout, "Usage:\n") diff --git a/oviewer/action.go b/oviewer/action.go index fe637428..f2955290 100644 --- a/oviewer/action.go +++ b/oviewer/action.go @@ -623,3 +623,55 @@ func (root *Root) updateEndNum() { root.drawStatus() root.Screen.Sync() } + +// follow updates the document in follow mode. +func (root *Root) follow() { + if root.General.FollowAll { + root.followAll() + } + num := root.Doc.BufEndNum() + if root.Doc.latestNum == num { + return + } + + root.skipDraw = false + if root.Doc.FollowSection { + root.tailSection() + } else { + root.TailSync() + } + root.Doc.latestNum = num +} + +// followAll monitors and switches all document updates +// in follow all mode. +func (root *Root) followAll() { + if root.screenMode != Docs { + return + } + + current := root.CurrentDoc + root.mu.RLock() + for n, doc := range root.DocList { + if doc.latestNum != doc.BufEndNum() { + current = n + } + } + root.mu.RUnlock() + + if root.CurrentDoc != current { + root.switchDocument(current) + } +} + +// Cancel follow mode and follow all mode. +func (root *Root) Cancel() { + root.General.FollowAll = false + root.Doc.FollowMode = false +} + +// WriteQuit sets the write flag and executes a quit event. +func (root *Root) WriteQuit() { + root.IsWriteOriginal = true + root.Quit() +} diff --git a/oviewer/control.go b/oviewer/control.go index c40f9215..6d997ed8 100644 --- a/oviewer/control.go +++ b/oviewer/control.go @@ -74,8 +74,8 @@ func (m *Document) ControlReader(r io.Reader, reload func() *bufio.Reader) error reader := bufio.NewReader(r) go func() { - var err error for sc := range m.ctlCh { + var err error reader, err = m.controlReader(sc, reader, reload) if err != nil { log.Println(sc.request, err) diff --git a/oviewer/event.go b/oviewer/event.go index fda11093..320aa572 100644 --- a/oviewer/event.go +++ b/oviewer/event.go @@ -181,58 +181,6 @@ func (root *Root) sendSuspend() { root.postEvent(ev) } -// Cancel follow mode and follow all mode. -func (root *Root) Cancel() { - root.General.FollowAll = false - root.Doc.FollowMode = false -} - -// WriteQuit sets the write flag and executes a quit event. -func (root *Root) WriteQuit() { - root.IsWriteOriginal = true - root.Quit() -} - -// follow updates the document in follow mode. -func (root *Root) follow() { - if root.General.FollowAll { - root.followAll() - } - num := root.Doc.BufEndNum() - if root.Doc.latestNum == num { - return - } - - root.skipDraw = false - if root.Doc.FollowSection { - root.tailSection() - } else { - root.TailSync() - } - root.Doc.latestNum = num -} - -// followAll monitors and switches all document updates -// in follow all mode. -func (root *Root) followAll() { - if root.screenMode != Docs { - return - } - - current := root.CurrentDoc - root.mu.RLock() - for n, doc := range root.DocList { - if doc.latestNum != doc.BufEndNum() { - current = n - } - } - root.mu.RUnlock() - - if root.CurrentDoc != current { - root.switchDocument(current) - } -} - // updateInterval calls eventUpdate at regular intervals. func (root *Root) updateInterval(ctx context.Context) { timer := time.NewTicker(UpdateInterval) diff --git a/oviewer/sigtstp.go b/oviewer/sigtstp.go index 7583caba..1a49d68b 100644 --- a/oviewer/sigtstp.go +++ b/oviewer/sigtstp.go @@ -9,6 +9,7 @@ import ( "syscall" ) +// registerSIGTSTP registers SIGTSTP signal. func registerSIGTSTP() chan os.Signal { sigSuspend := make(chan os.Signal, 1) signal.Notify(sigSuspend, syscall.SIGTSTP)