Skip to content

Commit c7c18e0

Browse files
authored
Revert "Add finalizers to ensure that repos are closed and blobreaders are closed (#19495) (#19496)" (#19659)
This reverts commit 88da506. because it caused a memleak
1 parent 0a2d618 commit c7c18e0

File tree

3 files changed

+18
-157
lines changed

3 files changed

+18
-157
lines changed

modules/git/blob_nogogit.go

Lines changed: 10 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ import (
1212
"bytes"
1313
"io"
1414
"math"
15-
"runtime"
16-
"sync"
1715

1816
"code.gitea.io/gitea/modules/log"
19-
"code.gitea.io/gitea/modules/process"
2017
)
2118

2219
// Blob represents a Git object.
@@ -57,15 +54,11 @@ func (b *Blob) DataAsync() (io.ReadCloser, error) {
5754
return io.NopCloser(bytes.NewReader(bs)), err
5855
}
5956

60-
br := &blobReader{
61-
repo: b.repo,
57+
return &blobReader{
6258
rd: rd,
6359
n: size,
6460
cancel: cancel,
65-
}
66-
runtime.SetFinalizer(br, (*blobReader).finalizer)
67-
68-
return br, nil
61+
}, nil
6962
}
7063

7164
// Size returns the uncompressed size of the blob
@@ -93,10 +86,6 @@ func (b *Blob) Size() int64 {
9386
}
9487

9588
type blobReader struct {
96-
lock sync.Mutex
97-
closed bool
98-
99-
repo *Repository
10089
rd *bufio.Reader
10190
n int64
10291
cancel func()
@@ -115,57 +104,27 @@ func (b *blobReader) Read(p []byte) (n int, err error) {
115104
}
116105

117106
// Close implements io.Closer
118-
func (b *blobReader) Close() (err error) {
119-
b.lock.Lock()
120-
defer b.lock.Unlock()
121-
if b.closed {
122-
return
123-
}
124-
return b.close()
125-
}
126-
127-
func (b *blobReader) close() (err error) {
107+
func (b *blobReader) Close() error {
128108
defer b.cancel()
129-
b.closed = true
130109
if b.n > 0 {
131-
var n int
132110
for b.n > math.MaxInt32 {
133-
n, err = b.rd.Discard(math.MaxInt32)
111+
n, err := b.rd.Discard(math.MaxInt32)
134112
b.n -= int64(n)
135113
if err != nil {
136-
return
114+
return err
137115
}
138116
b.n -= math.MaxInt32
139117
}
140-
n, err = b.rd.Discard(int(b.n))
118+
n, err := b.rd.Discard(int(b.n))
141119
b.n -= int64(n)
142120
if err != nil {
143-
return
121+
return err
144122
}
145123
}
146124
if b.n == 0 {
147-
_, err = b.rd.Discard(1)
125+
_, err := b.rd.Discard(1)
148126
b.n--
149-
return
150-
}
151-
return
152-
}
153-
154-
func (b *blobReader) finalizer() error {
155-
if b == nil {
156-
return nil
157-
}
158-
b.lock.Lock()
159-
defer b.lock.Unlock()
160-
if b.closed {
161-
return nil
127+
return err
162128
}
163-
164-
pid := ""
165-
if b.repo.Ctx != nil {
166-
pid = " from PID: " + string(process.GetPID(b.repo.Ctx))
167-
}
168-
log.Error("Finalizer running on unclosed blobReader%s: %s%s", pid, b.repo.Path)
169-
170-
return b.close()
129+
return nil
171130
}

modules/git/repo_base_gogit.go

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@ import (
1212
"context"
1313
"errors"
1414
"path/filepath"
15-
"runtime"
16-
"sync"
1715

18-
"code.gitea.io/gitea/modules/log"
1916
gitealog "code.gitea.io/gitea/modules/log"
20-
"code.gitea.io/gitea/modules/process"
2117
"code.gitea.io/gitea/modules/setting"
2218

2319
"github.com/go-git/go-billy/v5/osfs"
@@ -32,9 +28,6 @@ type Repository struct {
3228

3329
tagCache *ObjectCache
3430

35-
lock sync.Mutex
36-
closed bool
37-
3831
gogitRepo *gogit.Repository
3932
gogitStorage *filesystem.Storage
4033
gpgSettings *GPGSettings
@@ -70,57 +63,23 @@ func OpenRepositoryCtx(ctx context.Context, repoPath string) (*Repository, error
7063
return nil, err
7164
}
7265

73-
repo := &Repository{
66+
return &Repository{
7467
Path: repoPath,
7568
gogitRepo: gogitRepo,
7669
gogitStorage: storage,
7770
tagCache: newObjectCache(),
7871
Ctx: ctx,
79-
}
80-
81-
runtime.SetFinalizer(repo, (*Repository).finalizer)
82-
83-
return repo, nil
72+
}, nil
8473
}
8574

8675
// Close this repository, in particular close the underlying gogitStorage if this is not nil
87-
func (repo *Repository) Close() (err error) {
88-
if repo == nil {
89-
return
90-
}
91-
repo.lock.Lock()
92-
defer repo.lock.Unlock()
93-
return repo.close()
94-
}
95-
96-
func (repo *Repository) close() (err error) {
97-
repo.closed = true
98-
if repo.gogitStorage == nil {
76+
func (repo *Repository) Close() {
77+
if repo == nil || repo.gogitStorage == nil {
9978
return
10079
}
101-
err = repo.gogitStorage.Close()
102-
if err != nil {
80+
if err := repo.gogitStorage.Close(); err != nil {
10381
gitealog.Error("Error closing storage: %v", err)
10482
}
105-
return
106-
}
107-
108-
func (repo *Repository) finalizer() error {
109-
if repo == nil {
110-
return nil
111-
}
112-
repo.lock.Lock()
113-
defer repo.lock.Unlock()
114-
if !repo.closed {
115-
pid := ""
116-
if repo.Ctx != nil {
117-
pid = " from PID: " + string(process.GetPID(repo.Ctx))
118-
}
119-
log.Error("Finalizer running on unclosed repository%s: %s%s", pid, repo.Path)
120-
}
121-
122-
// We still need to run the close fn as it may be possible to reopen the gogitrepo after close
123-
return repo.close()
12483
}
12584

12685
// GoGitRepo gets the go-git repo representation

modules/git/repo_base_nogogit.go

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ import (
1313
"context"
1414
"errors"
1515
"path/filepath"
16-
"runtime"
17-
"sync"
1816

1917
"code.gitea.io/gitea/modules/log"
20-
"code.gitea.io/gitea/modules/process"
2118
)
2219

2320
// Repository represents a Git repository.
@@ -28,10 +25,6 @@ type Repository struct {
2825

2926
gpgSettings *GPGSettings
3027

31-
lock sync.Mutex
32-
33-
closed bool
34-
3528
batchCancel context.CancelFunc
3629
batchReader *bufio.Reader
3730
batchWriter WriteCloserError
@@ -71,57 +64,29 @@ func OpenRepositoryCtx(ctx context.Context, repoPath string) (*Repository, error
7164
repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath)
7265
repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repo.Path)
7366

74-
runtime.SetFinalizer(repo, (*Repository).finalizer)
75-
7667
return repo, nil
7768
}
7869

7970
// CatFileBatch obtains a CatFileBatch for this repository
8071
func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
81-
repo.lock.Lock()
82-
defer repo.lock.Unlock()
83-
84-
if repo.closed || repo.batchReader.Buffered() > 0 {
72+
if repo.batchCancel == nil || repo.batchReader.Buffered() > 0 {
8573
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
8674
return CatFileBatch(ctx, repo.Path)
8775
}
88-
89-
if repo.batchCancel == nil {
90-
repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repo.Path)
91-
}
92-
9376
return repo.batchWriter, repo.batchReader, func() {}
9477
}
9578

9679
// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
9780
func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
98-
repo.lock.Lock()
99-
defer repo.lock.Unlock()
100-
101-
if repo.closed || repo.checkReader.Buffered() > 0 {
81+
if repo.checkCancel == nil || repo.checkReader.Buffered() > 0 {
10282
log.Debug("Opening temporary cat file batch-check: %s", repo.Path)
10383
return CatFileBatchCheck(ctx, repo.Path)
10484
}
105-
106-
if repo.checkCancel == nil {
107-
repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repo.Path)
108-
}
109-
11085
return repo.checkWriter, repo.checkReader, func() {}
11186
}
11287

11388
// Close this repository, in particular close the underlying gogitStorage if this is not nil
114-
func (repo *Repository) Close() (err error) {
115-
if repo == nil {
116-
return
117-
}
118-
repo.lock.Lock()
119-
defer repo.lock.Unlock()
120-
121-
return repo.close()
122-
}
123-
124-
func (repo *Repository) close() (err error) {
89+
func (repo *Repository) Close() {
12590
if repo == nil {
12691
return
12792
}
@@ -137,26 +102,4 @@ func (repo *Repository) close() (err error) {
137102
repo.checkReader = nil
138103
repo.checkWriter = nil
139104
}
140-
repo.closed = true
141-
return
142-
}
143-
144-
func (repo *Repository) finalizer() (err error) {
145-
if repo == nil {
146-
return
147-
}
148-
repo.lock.Lock()
149-
defer repo.lock.Unlock()
150-
if repo.closed {
151-
return nil
152-
}
153-
154-
if repo.batchCancel != nil || repo.checkCancel != nil {
155-
pid := ""
156-
if repo.Ctx != nil {
157-
pid = " from PID: " + string(process.GetPID(repo.Ctx))
158-
}
159-
log.Error("Finalizer running on unclosed repository%s: %s%s", pid, repo.Path)
160-
}
161-
return repo.close()
162105
}

0 commit comments

Comments
 (0)