From 7d29d6864474525c9853d86996d769a5459dc15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 8 Jul 2017 11:38:19 +0200 Subject: [PATCH] Second round of keep-alives --- diff.go | 57 +++++++++++++++++++++++++++++++------------ git.go | 1 + graph.go | 6 +++++ ignore.go | 3 +++ index.go | 67 +++++++++++++++++++++++++++++++++++++++------------ repository.go | 3 +-- 6 files changed, 105 insertions(+), 32 deletions(-) diff --git a/diff.go b/diff.go index e8d5007..3cc1dc2 100644 --- a/diff.go +++ b/diff.go @@ -127,14 +127,17 @@ func diffLineFromC(line *C.git_diff_line) DiffLine { } type Diff struct { - ptr *C.git_diff + ptr *C.git_diff + repo *Repository } func (diff *Diff) NumDeltas() (int, error) { if diff.ptr == nil { return -1, ErrInvalid } - return int(C.git_diff_num_deltas(diff.ptr)), nil + ret := int(C.git_diff_num_deltas(diff.ptr)) + runtime.KeepAlive(diff) + return ret, nil } func (diff *Diff) GetDelta(index int) (DiffDelta, error) { @@ -142,16 +145,19 @@ func (diff *Diff) GetDelta(index int) (DiffDelta, error) { return DiffDelta{}, ErrInvalid } ptr := C.git_diff_get_delta(diff.ptr, C.size_t(index)) - return diffDeltaFromC(ptr), nil + ret := diffDeltaFromC(ptr) + runtime.KeepAlive(diff) + return ret, nil } -func newDiffFromC(ptr *C.git_diff) *Diff { +func newDiffFromC(ptr *C.git_diff, repo *Repository) *Diff { if ptr == nil { return nil } diff := &Diff{ - ptr: ptr, + ptr: ptr, + repo: repo, } runtime.SetFinalizer(diff, (*Diff).Free) @@ -187,6 +193,7 @@ func (diff *Diff) FindSimilar(opts *DiffFindOptions) error { defer runtime.UnlockOSThread() ecode := C.git_diff_find_similar(diff.ptr, copts) + runtime.KeepAlive(diff) if ecode < 0 { return MakeGitError(ecode) } @@ -209,15 +216,21 @@ func (stats *DiffStats) Free() error { } func (stats *DiffStats) Insertions() int { - return int(C.git_diff_stats_insertions(stats.ptr)) + ret := int(C.git_diff_stats_insertions(stats.ptr)) + runtime.KeepAlive(stats) + return ret } func (stats *DiffStats) Deletions() int { - return int(C.git_diff_stats_deletions(stats.ptr)) + ret := int(C.git_diff_stats_deletions(stats.ptr)) + runtime.KeepAlive(stats) + return ret } func (stats *DiffStats) FilesChanged() int { - return int(C.git_diff_stats_files_changed(stats.ptr)) + ret := int(C.git_diff_stats_files_changed(stats.ptr)) + runtime.KeepAlive(stats) + return ret } type DiffStatsFormat int @@ -240,6 +253,7 @@ func (stats *DiffStats) String(format DiffStatsFormat, ret := C.git_diff_stats_to_buf(&buf, stats.ptr, C.git_diff_stats_format_t(format), C.size_t(width)) + runtime.KeepAlive(stats) if ret < 0 { return "", MakeGitError(ret) } @@ -253,7 +267,9 @@ func (diff *Diff) Stats() (*DiffStats, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - if ecode := C.git_diff_get_stats(&stats.ptr, diff.ptr); ecode < 0 { + ecode := C.git_diff_get_stats(&stats.ptr, diff.ptr) + runtime.KeepAlive(diff) + if ecode < 0 { return nil, MakeGitError(ecode) } runtime.SetFinalizer(stats, (*DiffStats).Free) @@ -301,6 +317,7 @@ func (diff *Diff) ForEach(cbFile DiffForEachFileCallback, detail DiffDetail) err defer pointerHandles.Untrack(handle) ecode := C._go_git_diff_foreach(diff.ptr, 1, intHunks, intLines, handle) + runtime.KeepAlive(diff) if ecode < 0 { return data.Error } @@ -380,6 +397,7 @@ func (diff *Diff) Patch(deltaIndex int) (*Patch, error) { defer runtime.UnlockOSThread() ecode := C.git_patch_from_diff(&patchPtr, diff.ptr, C.size_t(deltaIndex)) + runtime.KeepAlive(diff) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -537,7 +555,7 @@ func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, m if data != nil { if data.Diff == nil { - data.Diff = newDiffFromC(diff_so_far) + data.Diff = newDiffFromC(diff_so_far, nil) } err := data.Callback(data.Diff, diffDeltaFromC(delta_to_add), C.GoString(matched_pathspec)) @@ -618,6 +636,8 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) ( defer runtime.UnlockOSThread() ecode := C.git_diff_tree_to_tree(&diffPtr, v.ptr, oldPtr, newPtr, copts) + runtime.KeepAlive(oldTree) + runtime.KeepAlive(newTree) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -625,7 +645,7 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) ( if notifyData != nil && notifyData.Diff != nil { return notifyData.Diff, nil } - return newDiffFromC(diffPtr), nil + return newDiffFromC(diffPtr, v), nil } func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff, error) { @@ -643,6 +663,7 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff, defer runtime.UnlockOSThread() ecode := C.git_diff_tree_to_workdir(&diffPtr, v.ptr, oldPtr, copts) + runtime.KeepAlive(oldTree) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -650,7 +671,7 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff, if notifyData != nil && notifyData.Diff != nil { return notifyData.Diff, nil } - return newDiffFromC(diffPtr), nil + return newDiffFromC(diffPtr, v), nil } func (v *Repository) DiffTreeToIndex(oldTree *Tree, index *Index, opts *DiffOptions) (*Diff, error) { @@ -673,6 +694,8 @@ func (v *Repository) DiffTreeToIndex(oldTree *Tree, index *Index, opts *DiffOpti defer runtime.UnlockOSThread() ecode := C.git_diff_tree_to_index(&diffPtr, v.ptr, oldPtr, indexPtr, copts) + runtime.KeepAlive(oldTree) + runtime.KeepAlive(index) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -680,7 +703,7 @@ func (v *Repository) DiffTreeToIndex(oldTree *Tree, index *Index, opts *DiffOpti if notifyData != nil && notifyData.Diff != nil { return notifyData.Diff, nil } - return newDiffFromC(diffPtr), nil + return newDiffFromC(diffPtr, v), nil } func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions) (*Diff, error) { @@ -698,6 +721,7 @@ func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions defer runtime.UnlockOSThread() ecode := C.git_diff_tree_to_workdir_with_index(&diffPtr, v.ptr, oldPtr, copts) + runtime.KeepAlive(oldTree) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -705,7 +729,7 @@ func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions if notifyData != nil && notifyData.Diff != nil { return notifyData.Diff, nil } - return newDiffFromC(diffPtr), nil + return newDiffFromC(diffPtr, v), nil } func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff, error) { @@ -723,6 +747,7 @@ func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff, defer runtime.UnlockOSThread() ecode := C.git_diff_index_to_workdir(&diffPtr, v.ptr, indexPtr, copts) + runtime.KeepAlive(index) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -730,7 +755,7 @@ func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff, if notifyData != nil && notifyData.Diff != nil { return notifyData.Diff, nil } - return newDiffFromC(diffPtr), nil + return newDiffFromC(diffPtr, v), nil } // DiffBlobs performs a diff between two arbitrary blobs. You can pass @@ -773,6 +798,8 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, defer runtime.UnlockOSThread() ecode := C._go_git_diff_blobs(oldBlobPtr, oldBlobPath, newBlobPtr, newBlobPath, copts, 1, intHunks, intLines, handle) + runtime.KeepAlive(oldBlob) + runtime.KeepAlive(newBlob) if ecode < 0 { return MakeGitError(ecode) } diff --git a/git.go b/git.go index 5181b8b..0925e45 100644 --- a/git.go +++ b/git.go @@ -232,6 +232,7 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) { return int(ret), MakeGitError(ret) } } + runtime.KeepAlive(ids) return int(ret), nil } diff --git a/graph.go b/graph.go index e5d7732..688818c 100644 --- a/graph.go +++ b/graph.go @@ -13,6 +13,9 @@ func (repo *Repository) DescendantOf(commit, ancestor *Oid) (bool, error) { defer runtime.UnlockOSThread() ret := C.git_graph_descendant_of(repo.ptr, commit.toC(), ancestor.toC()) + runtime.KeepAlive(repo) + runtime.KeepAlive(commit) + runtime.KeepAlive(ancestor) if ret < 0 { return false, MakeGitError(ret) } @@ -28,6 +31,9 @@ func (repo *Repository) AheadBehind(local, upstream *Oid) (ahead, behind int, er var behindT C.size_t ret := C.git_graph_ahead_behind(&aheadT, &behindT, repo.ptr, local.toC(), upstream.toC()) + runtime.KeepAlive(repo) + runtime.KeepAlive(local) + runtime.KeepAlive(upstream) if ret < 0 { return 0, 0, MakeGitError(ret) } diff --git a/ignore.go b/ignore.go index 6b12348..c698de1 100644 --- a/ignore.go +++ b/ignore.go @@ -17,6 +17,7 @@ func (v *Repository) AddIgnoreRule(rules string) error { defer runtime.UnlockOSThread() ret := C.git_ignore_add_rule(v.ptr, crules) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -28,6 +29,7 @@ func (v *Repository) ClearInternalIgnoreRules() error { defer runtime.UnlockOSThread() ret := C.git_ignore_clear_internal_rules(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -44,6 +46,7 @@ func (v *Repository) IsPathIgnored(path string) (bool, error) { defer runtime.UnlockOSThread() ret := C.git_ignore_path_is_ignored(&ignored, v.ptr, cpath) + runtime.KeepAlive(v) if ret < 0 { return false, MakeGitError(ret) } diff --git a/index.go b/index.go index 2afdcdf..5106516 100644 --- a/index.go +++ b/index.go @@ -45,7 +45,8 @@ const ( ) type Index struct { - ptr *C.git_index + ptr *C.git_index + repo *Repository } type IndexTime struct { @@ -97,8 +98,8 @@ func freeCIndexEntry(entry *C.git_index_entry) { C.free(unsafe.Pointer(entry.path)) } -func newIndexFromC(ptr *C.git_index) *Index { - idx := &Index{ptr} +func newIndexFromC(ptr *C.git_index, repo *Repository) *Index { + idx := &Index{ptr, repo} runtime.SetFinalizer(idx, (*Index).Free) return idx } @@ -115,7 +116,7 @@ func NewIndex() (*Index, error) { return nil, MakeGitError(err) } - return newIndexFromC(ptr), nil + return newIndexFromC(ptr, nil), nil } // OpenIndex creates a new index at the given path. If the file does @@ -133,13 +134,15 @@ func OpenIndex(path string) (*Index, error) { return nil, MakeGitError(err) } - return newIndexFromC(ptr), nil + return newIndexFromC(ptr, nil), nil } // Path returns the index' path on disk or an empty string if it // exists only in memory. func (v *Index) Path() string { - return C.GoString(C.git_index_path(v.ptr)) + ret := C.GoString(C.git_index_path(v.ptr)) + runtime.KeepAlive(v) + return ret } // Add adds or replaces the given entry to the index, making a copy of @@ -153,7 +156,9 @@ func (v *Index) Add(entry *IndexEntry) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - if err := C.git_index_add(v.ptr, ¢ry); err < 0 { + err := C.git_index_add(v.ptr, ¢ry) + runtime.KeepAlive(v) + if err < 0 { return MakeGitError(err) } @@ -168,6 +173,7 @@ func (v *Index) AddByPath(path string) error { defer runtime.UnlockOSThread() ret := C.git_index_add_bypath(v.ptr, cstr) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -196,6 +202,7 @@ func (v *Index) AddAll(pathspecs []string, flags IndexAddOpts, callback IndexMat C.uint(flags), handle, ) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -222,6 +229,7 @@ func (v *Index) UpdateAll(pathspecs []string, callback IndexMatchedPathCallback) &cpathspecs, handle, ) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -248,6 +256,7 @@ func (v *Index) RemoveAll(pathspecs []string, callback IndexMatchedPathCallback) &cpathspecs, handle, ) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -271,6 +280,7 @@ func (v *Index) RemoveByPath(path string) error { defer runtime.UnlockOSThread() ret := C.git_index_remove_bypath(v.ptr, cstr) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -287,6 +297,7 @@ func (v *Index) RemoveDirectory(dir string, stage int) error { defer runtime.UnlockOSThread() ret := C.git_index_remove_directory(v.ptr, cstr, C.int(stage)) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -301,6 +312,8 @@ func (v *Index) WriteTreeTo(repo *Repository) (*Oid, error) { defer runtime.UnlockOSThread() ret := C.git_index_write_tree_to(oid.toC(), v.ptr, repo.ptr) + runtime.KeepAlive(v) + runtime.KeepAlive(repo) if ret < 0 { return nil, MakeGitError(ret) } @@ -315,6 +328,8 @@ func (v *Index) ReadTree(tree *Tree) error { defer runtime.UnlockOSThread() ret := C.git_index_read_tree(v.ptr, tree.cast_ptr) + runtime.KeepAlive(v) + runtime.KeepAlive(tree) if ret < 0 { return MakeGitError(ret) } @@ -329,6 +344,7 @@ func (v *Index) WriteTree() (*Oid, error) { defer runtime.UnlockOSThread() ret := C.git_index_write_tree(oid.toC(), v.ptr) + runtime.KeepAlive(v) if ret < 0 { return nil, MakeGitError(ret) } @@ -341,6 +357,7 @@ func (v *Index) Write() error { defer runtime.UnlockOSThread() ret := C.git_index_write(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -354,7 +371,9 @@ func (v *Index) Free() { } func (v *Index) EntryCount() uint { - return uint(C.git_index_entrycount(v.ptr)) + ret := uint(C.git_index_entrycount(v.ptr)) + runtime.KeepAlive(v) + return ret } func (v *Index) EntryByIndex(index uint) (*IndexEntry, error) { @@ -362,7 +381,9 @@ func (v *Index) EntryByIndex(index uint) (*IndexEntry, error) { if centry == nil { return nil, fmt.Errorf("Index out of Bounds") } - return newIndexEntryFromC(centry), nil + ret := newIndexEntryFromC(centry) + runtime.KeepAlive(v) + return ret, nil } func (v *Index) EntryByPath(path string, stage int) (*IndexEntry, error) { @@ -376,7 +397,9 @@ func (v *Index) EntryByPath(path string, stage int) (*IndexEntry, error) { if centry == nil { return nil, MakeGitError(C.GIT_ENOTFOUND) } - return newIndexEntryFromC(centry), nil + ret := newIndexEntryFromC(centry) + runtime.KeepAlive(v) + return ret, nil } func (v *Index) Find(path string) (uint, error) { @@ -388,6 +411,7 @@ func (v *Index) Find(path string) (uint, error) { var pos C.size_t ret := C.git_index_find(&pos, v.ptr, cpath) + runtime.KeepAlive(v) if ret < 0 { return uint(0), MakeGitError(ret) } @@ -403,6 +427,7 @@ func (v *Index) FindPrefix(prefix string) (uint, error) { var pos C.size_t ret := C.git_index_find_prefix(&pos, v.ptr, cprefix) + runtime.KeepAlive(v) if ret < 0 { return uint(0), MakeGitError(ret) } @@ -410,12 +435,15 @@ func (v *Index) FindPrefix(prefix string) (uint, error) { } func (v *Index) HasConflicts() bool { - return C.git_index_has_conflicts(v.ptr) != 0 + ret := C.git_index_has_conflicts(v.ptr) != 0 + runtime.KeepAlive(v) + return ret } // FIXME: this might return an error func (v *Index) CleanupConflicts() { C.git_index_conflict_cleanup(v.ptr) + runtime.KeepAlive(v) } func (v *Index) AddConflict(ancestor *IndexEntry, our *IndexEntry, their *IndexEntry) error { @@ -446,6 +474,10 @@ func (v *Index) AddConflict(ancestor *IndexEntry, our *IndexEntry, their *IndexE defer runtime.UnlockOSThread() ecode := C.git_index_conflict_add(v.ptr, cancestor, cour, ctheir) + runtime.KeepAlive(v) + runtime.KeepAlive(ancestor) + runtime.KeepAlive(our) + runtime.KeepAlive(their) if ecode < 0 { return MakeGitError(ecode) } @@ -474,11 +506,13 @@ func (v *Index) GetConflict(path string) (IndexConflict, error) { if ecode < 0 { return IndexConflict{}, MakeGitError(ecode) } - return IndexConflict{ + ret := IndexConflict{ Ancestor: newIndexEntryFromC(cancestor), Our: newIndexEntryFromC(cour), Their: newIndexEntryFromC(ctheir), - }, nil + } + runtime.KeepAlive(v) + return ret, nil } func (v *Index) RemoveConflict(path string) error { @@ -490,6 +524,7 @@ func (v *Index) RemoveConflict(path string) error { defer runtime.UnlockOSThread() ecode := C.git_index_conflict_remove(v.ptr, cpath) + runtime.KeepAlive(v) if ecode < 0 { return MakeGitError(ecode) } @@ -541,9 +576,11 @@ func (v *IndexConflictIterator) Next() (IndexConflict, error) { if ecode < 0 { return IndexConflict{}, MakeGitError(ecode) } - return IndexConflict{ + ret := IndexConflict{ Ancestor: newIndexEntryFromC(cancestor), Our: newIndexEntryFromC(cour), Their: newIndexEntryFromC(ctheir), - }, nil + } + runtime.KeepAlive(v) + return ret, nil } diff --git a/repository.go b/repository.go index 44d18a9..6b07e87 100644 --- a/repository.go +++ b/repository.go @@ -160,12 +160,11 @@ func (v *Repository) Index() (*Index, error) { defer runtime.UnlockOSThread() ret := C.git_repository_index(&ptr, v.ptr) - runtime.KeepAlive(v) if ret < 0 { return nil, MakeGitError(ret) } - return newIndexFromC(ptr), nil + return newIndexFromC(ptr, v), nil } func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) {