Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to wait for EOF #673

Merged
merged 2 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions oviewer/control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand Down
14 changes: 14 additions & 0 deletions oviewer/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ type Document struct {
// alignConv is an interface that converts alignment.
alignConv *align

cond *sync.Cond
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need this?

I have never faced sync.Cond until now, so I looked at documentation

https://pkg.go.dev/sync#Cond

For many simple use cases, users will be better off using channels than a Cond

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need this?

I have never faced sync.Cond until now, so I looked at documentation

https://pkg.go.dev/sync#Cond

For many simple use cases, users will be better off using channels than a Cond

That's a good point.
I thought it would be best to use Broadcast (), which does not have to be received or does not need to receive more than one.
I think it is difficult to implement it without mistakes on a channel.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK then


// fileName is the file name to display.
FileName string
// Caption is an additional caption to display after the file name.
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -428,6 +432,16 @@ 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 m.BufEOF() {
return
}
m.cond.Wait()
}

// BufEOF return true if EOF is reached.
func (m *Document) BufEOF() bool {
return atomic.LoadInt32(&m.store.eof) == 1
Expand Down
9 changes: 2 additions & 7 deletions oviewer/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down Expand Up @@ -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)
Expand Down
11 changes: 5 additions & 6 deletions oviewer/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions oviewer/oviewer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions oviewer/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Loading