From 05d0c4660ba52fefe06f46abbe7a36ff459025d7 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Wed, 25 Dec 2024 10:55:07 +0900 Subject: [PATCH 1/2] Add function to wait for EOF Added `WaitEOF` function to wait for EOF notification. --- oviewer/control_test.go | 15 ++++----------- oviewer/document.go | 13 +++++++++++++ oviewer/document_test.go | 9 ++------- oviewer/filter_test.go | 11 +++++------ oviewer/oviewer_test.go | 3 +-- oviewer/reader.go | 3 +++ 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/oviewer/control_test.go b/oviewer/control_test.go index 04edade1..1d87d925 100644 --- a/oviewer/control_test.go +++ b/oviewer/control_test.go @@ -161,9 +161,7 @@ func TestDocument_requestLoad(t *testing.T) { if err := m.ControlFile(f); err != nil { t.Fatalf("Document.ControlFile() fatal = %v, wantErr %v", err, tt.wantErr) } - for !m.BufEOF() { - } - + m.WaitEOF() m.requestLoad(tt.fields.chunkNum) sc := controlSpecifier{ @@ -235,8 +233,7 @@ func TestDocument_requestSearch(t *testing.T) { if err := m.ControlFile(f); (err != nil) != tt.wantErr { t.Errorf("Document.ControlFile() error = %v, wantErr %v", err, tt.wantErr) } - for !m.BufEOF() { - } + m.WaitEOF() if got := m.requestSearch(tt.fields.chunkNum, searcher); got != tt.want { t.Errorf("Document.requestSearch() = %v, want %v", got, tt.want) } @@ -304,10 +301,7 @@ func TestDocument_requestFollow(t *testing.T) { if err := m.ControlFile(f); err != nil { t.Fatalf("Document.ControlFile() fatal = %v, wantErr %v", err, tt.wantErr) } - - for !m.BufEOF() { - } - + m.WaitEOF() af, err := os.OpenFile(fname, os.O_APPEND|os.O_RDWR, 0o600) if err != nil { t.Fatal("open error", tt.fields.FileName) @@ -371,8 +365,7 @@ func TestDocument_requestClose(t *testing.T) { if err := m.ControlFile(f); (err != nil) != tt.wantErr { t.Errorf("Document.ControlFile() error = %v, wantErr %v", err, tt.wantErr) } - for !m.BufEOF() { - } + m.WaitEOF() if got := m.requestClose(); got != tt.want { t.Errorf("Document.requestSearch() = %v, want %v", got, tt.want) } diff --git a/oviewer/document.go b/oviewer/document.go index e13640c4..470d327c 100644 --- a/oviewer/document.go +++ b/oviewer/document.go @@ -59,6 +59,8 @@ type Document struct { // alignConv is an interface that converts alignment. alignConv *align + cond *sync.Cond + // fileName is the file name to display. FileName string // Caption is an additional caption to display after the file name. @@ -232,6 +234,8 @@ func NewDocument() (*Document, error) { } m.alignConv = newAlignConverter(m.ColumnWidth) m.conv = m.converterType(m.general.Converter) + + m.cond = sync.NewCond(&sync.Mutex{}) return m, nil } @@ -428,6 +432,15 @@ func (m *Document) storeEndNum() int { return int(atomic.LoadInt32(&m.store.endNum)) } +// WaitEOF waits for EOF. +func (m *Document) WaitEOF() { + m.cond.L.Lock() + defer m.cond.L.Unlock() + if atomic.LoadInt32(&m.store.eof) == 0 { + m.cond.Wait() + } +} + // BufEOF return true if EOF is reached. func (m *Document) BufEOF() bool { return atomic.LoadInt32(&m.store.eof) == 1 diff --git a/oviewer/document_test.go b/oviewer/document_test.go index a606c59c..5cef3fb4 100644 --- a/oviewer/document_test.go +++ b/oviewer/document_test.go @@ -17,8 +17,7 @@ func docHelper(t *testing.T, str string) *Document { if err := m.ControlReader(bytes.NewBufferString(str), nil); err != nil { t.Fatal(err) } - for !m.BufEOF() { - } + m.WaitEOF() return m } @@ -28,9 +27,7 @@ func docFileReadHelper(t *testing.T, fileName string) *Document { if err != nil { t.Fatal(err) } - for !m.BufEOF() { - } - + m.WaitEOF() return m } @@ -162,8 +159,6 @@ func TestDocument_Export(t *testing.T) { t.Parallel() m := docHelper(t, tt.str) w := &bytes.Buffer{} - for !m.BufEOF() { - } m.bottomLN = m.BufEndNum() if err := m.Export(w, tt.args.start, tt.args.end); err != nil { t.Fatal(err) diff --git a/oviewer/filter_test.go b/oviewer/filter_test.go index b73f868f..8f724c17 100644 --- a/oviewer/filter_test.go +++ b/oviewer/filter_test.go @@ -174,8 +174,9 @@ func TestRoot_filterDocument(t *testing.T) { root.Doc.Header = tt.fields.header root.filterDocument(context.Background(), tt.args.searcher) filterDoc := root.DocList[len(root.DocList)-1] - for !filterDoc.BufEOF() { - } + filterDoc.cond.L.Lock() + filterDoc.cond.Wait() + filterDoc.cond.L.Unlock() line := filterDoc.getLineC(0) if line.str != tt.want { t.Errorf("filterDocument() = %v, want %v", line.str, tt.want) @@ -242,8 +243,7 @@ func TestRoot_filterLink(t *testing.T) { ctx := context.Background() root.filterDocument(ctx, tt.args.searcher) filterDoc := root.DocList[len(root.DocList)-1] - for !filterDoc.BufEOF() { - } + filterDoc.WaitEOF() filterDoc.LineNumMode = true root.prepareStartX() filterDoc.topLN = 2 @@ -299,8 +299,7 @@ func TestRoot_closeAllFilter(t *testing.T) { root := rootFileReadHelper(t, tt.fields.fileNames...) root.filterDocument(context.Background(), tt.args.searcher) filterDoc := root.DocList[len(root.DocList)-1] - for !filterDoc.BufEOF() { - } + filterDoc.WaitEOF() ctx := context.Background() root.closeAllFilter(ctx) if len(root.DocList) != tt.want { diff --git a/oviewer/oviewer_test.go b/oviewer/oviewer_test.go index b447f222..f25df3c7 100644 --- a/oviewer/oviewer_test.go +++ b/oviewer/oviewer_test.go @@ -43,8 +43,7 @@ func rootFileReadHelper(t *testing.T, fileNames ...string) *Root { } root.mu.RLock() for _, doc := range root.DocList { - for !doc.BufEOF() { - } + doc.WaitEOF() } root.mu.RUnlock() return root diff --git a/oviewer/reader.go b/oviewer/reader.go index ace46467..3c548662 100644 --- a/oviewer/reader.go +++ b/oviewer/reader.go @@ -268,6 +268,9 @@ func (m *Document) afterEOF(reader *bufio.Reader) *bufio.Reader { atomic.StoreInt32(&m.tmpLN, atomic.LoadInt32(&m.followStore.endNum)) m.cache.Purge() } + m.cond.L.Lock() + m.cond.Broadcast() + m.cond.L.Unlock() if !m.seekable { // for NamedPipe. return bufio.NewReader(m.file) } From c3360152070dc0f5559af50cc98a7018bf5c455e Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Fri, 27 Dec 2024 08:09:04 +0900 Subject: [PATCH 2/2] Update oviewer/document.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- oviewer/document.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/oviewer/document.go b/oviewer/document.go index 470d327c..be29f6c0 100644 --- a/oviewer/document.go +++ b/oviewer/document.go @@ -436,9 +436,10 @@ func (m *Document) storeEndNum() int { func (m *Document) WaitEOF() { m.cond.L.Lock() defer m.cond.L.Unlock() - if atomic.LoadInt32(&m.store.eof) == 0 { - m.cond.Wait() + if m.BufEOF() { + return } + m.cond.Wait() } // BufEOF return true if EOF is reached.