From 5d466ffbc00bc2fbde0f0589c70e23b8fc7cc7d9 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Fri, 7 Jul 2017 23:24:54 +0200 Subject: commit: add thread locking to signature extraction --- commit.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'commit.go') diff --git a/commit.go b/commit.go index fc2815a..fc04e1e 100644 --- a/commit.go +++ b/commit.go @@ -35,16 +35,18 @@ func (c Commit) ExtractSignature() (string, string, error) { defer C.git_buf_free(&c_signature) oid := c.Id() - repo := C.git_commit_owner(c.cast_ptr) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() ret := C.git_commit_extract_signature(&c_signature, &c_signed, repo, oid.toC(), nil) - + if ret < 0 { - return "", "", MakeGitError(ret) + return "", "", MakeGitError(ret) } else { return C.GoString(c_signature.ptr), C.GoString(c_signed.ptr), nil } - + } func (c Commit) Summary() string { -- cgit v1.2.3 From 0e9336be3f590b900a28a48b265dd2eab7836e03 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Fri, 7 Jul 2017 23:36:04 +0200 Subject: commit: add keep-alives for those that need conversion to pointer receivers We can't work on the copies here, we need to have pointer receivers so we know we're keeping alive the object whose finalizer would free the unmanaged memory we're working with. --- commit.go | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'commit.go') diff --git a/commit.go b/commit.go index fc04e1e..3ccb5da 100644 --- a/commit.go +++ b/commit.go @@ -18,15 +18,19 @@ type Commit struct { cast_ptr *C.git_commit } -func (c Commit) Message() string { - return C.GoString(C.git_commit_message(c.cast_ptr)) +func (c *Commit) Message() string { + ret := C.GoString(C.git_commit_message(c.cast_ptr)) + runtime.KeepAlive(c) + return ret } -func (c Commit) RawMessage() string { - return C.GoString(C.git_commit_message_raw(c.cast_ptr)) +func (c *Commit) RawMessage() string { + ret := C.GoString(C.git_commit_message_raw(c.cast_ptr)) + runtime.KeepAlive(c) + return ret } -func (c Commit) ExtractSignature() (string, string, error) { +func (c *Commit) ExtractSignature() (string, string, error) { var c_signed C.git_buf defer C.git_buf_free(&c_signed) @@ -40,7 +44,7 @@ func (c Commit) ExtractSignature() (string, string, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() ret := C.git_commit_extract_signature(&c_signature, &c_signed, repo, oid.toC(), nil) - + runtime.KeepAlive(oid) if ret < 0 { return "", "", MakeGitError(ret) } else { @@ -49,17 +53,20 @@ func (c Commit) ExtractSignature() (string, string, error) { } -func (c Commit) Summary() string { - return C.GoString(C.git_commit_summary(c.cast_ptr)) +func (c *Commit) Summary() string { + ret := C.GoString(C.git_commit_summary(c.cast_ptr)) + runtime.KeepAlive(c) + return ret } -func (c Commit) Tree() (*Tree, error) { +func (c *Commit) Tree() (*Tree, error) { var ptr *C.git_tree runtime.LockOSThread() defer runtime.UnlockOSThread() err := C.git_commit_tree(&ptr, c.cast_ptr) + runtime.KeepAlive(c) if err < 0 { return nil, MakeGitError(err) } @@ -67,18 +74,24 @@ func (c Commit) Tree() (*Tree, error) { return allocTree(ptr, c.repo), nil } -func (c Commit) TreeId() *Oid { - return newOidFromC(C.git_commit_tree_id(c.cast_ptr)) +func (c *Commit) TreeId() *Oid { + ret := newOidFromC(C.git_commit_tree_id(c.cast_ptr)) + runtime.KeepAlive(c) + return c } -func (c Commit) Author() *Signature { +func (c *Commit) Author() *Signature { cast_ptr := C.git_commit_author(c.cast_ptr) - return newSignatureFromC(cast_ptr) + ret := newSignatureFromC(cast_ptr) + runtime.KeepAlive(c) + return ret } -func (c Commit) Committer() *Signature { +func (c *Commit) Committer() *Signature { cast_ptr := C.git_commit_committer(c.cast_ptr) - return newSignatureFromC(cast_ptr) + ret := newSignatureFromC(cast_ptr) + runtime.KeepAlive(c) + return ret } func (c *Commit) Parent(n uint) *Commit { -- cgit v1.2.3 From 58334cf60441bd713b8fd990e30e0580b97bf3ae Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Fri, 7 Jul 2017 23:45:09 +0200 Subject: First round of mass keep-alive additions --- blame.go | 8 +++++++- blob.go | 23 +++++++++++++++++------ branch.go | 12 ++++++++++++ checkout.go | 3 +++ cherrypick.go | 2 ++ commit.go | 17 +++++++++++++---- config.go | 29 +++++++++++++++++++++++------ describe.go | 3 +++ repository.go | 47 ++++++++++++++++++++++++++++++++++++++++------- 9 files changed, 120 insertions(+), 24 deletions(-) (limited to 'commit.go') diff --git a/blame.go b/blame.go index b07d6bc..de32bb3 100644 --- a/blame.go +++ b/blame.go @@ -76,6 +76,7 @@ func (v *Repository) BlameFile(path string, opts *BlameOptions) (*Blame, error) defer runtime.UnlockOSThread() ecode := C.git_blame_file(&blamePtr, v.ptr, cpath, copts) + runtime.KeepAlive(v) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -88,11 +89,15 @@ type Blame struct { } func (blame *Blame) HunkCount() int { - return int(C.git_blame_get_hunk_count(blame.ptr)) + ret := int(C.git_blame_get_hunk_count(blame.ptr)) + runtime.KeepAlive(blame) + + return ret } func (blame *Blame) HunkByIndex(index int) (BlameHunk, error) { ptr := C.git_blame_get_hunk_byindex(blame.ptr, C.uint32_t(index)) + runtime.KeepAlive(blame) if ptr == nil { return BlameHunk{}, ErrInvalid } @@ -101,6 +106,7 @@ func (blame *Blame) HunkByIndex(index int) (BlameHunk, error) { func (blame *Blame) HunkByLine(lineno int) (BlameHunk, error) { ptr := C.git_blame_get_hunk_byline(blame.ptr, C.size_t(lineno)) + runtime.KeepAlive(blame) if ptr == nil { return BlameHunk{}, ErrInvalid } diff --git a/blob.go b/blob.go index 73a4a19..5235597 100644 --- a/blob.go +++ b/blob.go @@ -21,13 +21,19 @@ type Blob struct { } func (v *Blob) Size() int64 { - return int64(C.git_blob_rawsize(v.cast_ptr)) + ret := int64(C.git_blob_rawsize(v.cast_ptr)) + runtime.KeepAlive(v) + return ret } func (v *Blob) Contents() []byte { size := C.int(C.git_blob_rawsize(v.cast_ptr)) buffer := unsafe.Pointer(C.git_blob_rawcontent(v.cast_ptr)) - return C.GoBytes(buffer, size) + + goBytes := C.GoBytes(buffer, size) + runtime.KeepAlive(v) + + return goBytes } func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) { @@ -53,6 +59,7 @@ func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) { } ecode := C.git_blob_create_frombuffer(&id, repo.ptr, unsafe.Pointer(&data[0]), size) + runtime.KeepAlive(repo) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -102,16 +109,18 @@ func (repo *Repository) CreateFromStream(hintPath string) (*BlobWriteStream, err return nil, MakeGitError(ecode) } - return newBlobWriteStreamFromC(stream), nil + return newBlobWriteStreamFromC(stream, repo), nil } type BlobWriteStream struct { - ptr *C.git_writestream + ptr *C.git_writestream + repo *Repository } -func newBlobWriteStreamFromC(ptr *C.git_writestream) *BlobWriteStream { +func newBlobWriteStreamFromC(ptr *C.git_writestream, repo *Repository) *BlobWriteStream { stream := &BlobWriteStream{ - ptr: ptr, + ptr: ptr, + repo: repo, } runtime.SetFinalizer(stream, (*BlobWriteStream).Free) @@ -128,6 +137,7 @@ func (stream *BlobWriteStream) Write(p []byte) (int, error) { defer runtime.UnlockOSThread() ecode := C._go_git_writestream_write(stream.ptr, ptr, size) + runtime.KeepAlive(stream) if ecode < 0 { return 0, MakeGitError(ecode) } @@ -147,6 +157,7 @@ func (stream *BlobWriteStream) Commit() (*Oid, error) { defer runtime.UnlockOSThread() ecode := C.git_blob_create_fromstream_commit(&oid, stream.ptr) + runtime.KeepAlive(stream) if ecode < 0 { return nil, MakeGitError(ecode) } diff --git a/branch.go b/branch.go index d381c23..d6e7a53 100644 --- a/branch.go +++ b/branch.go @@ -88,6 +88,7 @@ func (repo *Repository) NewBranchIterator(flags BranchType) (*BranchIterator, er defer runtime.UnlockOSThread() ecode := C.git_branch_iterator_new(&ptr, repo.ptr, refType) + runtime.KeepAlive(repo) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -106,6 +107,8 @@ func (repo *Repository) CreateBranch(branchName string, target *Commit, force bo defer runtime.UnlockOSThread() ret := C.git_branch_create(&ptr, repo.ptr, cBranchName, target.cast_ptr, cForce) + runtime.KeepAlive(repo) + runtime.KeepAlive(target) if ret < 0 { return nil, MakeGitError(ret) } @@ -117,6 +120,7 @@ func (b *Branch) Delete() error { runtime.LockOSThread() defer runtime.UnlockOSThread() ret := C.git_branch_delete(b.Reference.ptr) + runtime.KeepAlive(b.Reference) if ret < 0 { return MakeGitError(ret) } @@ -133,6 +137,7 @@ func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) { defer runtime.UnlockOSThread() ret := C.git_branch_move(&ptr, b.Reference.ptr, cNewBranchName, cForce) + runtime.KeepAlive(b.Reference) if ret < 0 { return nil, MakeGitError(ret) } @@ -145,6 +150,7 @@ func (b *Branch) IsHead() (bool, error) { defer runtime.UnlockOSThread() ret := C.git_branch_is_head(b.Reference.ptr) + runtime.KeepAlive(b.Reference) switch ret { case 1: return true, nil @@ -165,6 +171,7 @@ func (repo *Repository) LookupBranch(branchName string, bt BranchType) (*Branch, defer runtime.UnlockOSThread() ret := C.git_branch_lookup(&ptr, repo.ptr, cName, C.git_branch_t(bt)) + runtime.KeepAlive(repo) if ret < 0 { return nil, MakeGitError(ret) } @@ -179,6 +186,7 @@ func (b *Branch) Name() (string, error) { defer runtime.UnlockOSThread() ret := C.git_branch_name(&cName, b.Reference.ptr) + runtime.KeepAlive(b.Reference) if ret < 0 { return "", MakeGitError(ret) } @@ -196,6 +204,7 @@ func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) { defer runtime.UnlockOSThread() ret := C.git_branch_remote_name(&nameBuf, repo.ptr, cName) + runtime.KeepAlive(repo) if ret < 0 { return "", MakeGitError(ret) } @@ -212,6 +221,7 @@ func (b *Branch) SetUpstream(upstreamName string) error { defer runtime.UnlockOSThread() ret := C.git_branch_set_upstream(b.Reference.ptr, cName) + runtime.KeepAlive(b.Reference) if ret < 0 { return MakeGitError(ret) } @@ -225,6 +235,7 @@ func (b *Branch) Upstream() (*Reference, error) { defer runtime.UnlockOSThread() ret := C.git_branch_upstream(&ptr, b.Reference.ptr) + runtime.KeepAlive(b.Reference) if ret < 0 { return nil, MakeGitError(ret) } @@ -241,6 +252,7 @@ func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) defer runtime.UnlockOSThread() ret := C.git_branch_upstream_name(&nameBuf, repo.ptr, cName) + runtime.KeepAlive(repo) if ret < 0 { return "", MakeGitError(ret) } diff --git a/checkout.go b/checkout.go index f5822c9..db3118f 100644 --- a/checkout.go +++ b/checkout.go @@ -188,6 +188,7 @@ func (v *Repository) CheckoutHead(opts *CheckoutOpts) error { defer freeCheckoutOpts(cOpts) ret := C.git_checkout_head(v.ptr, cOpts) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -211,6 +212,7 @@ func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error { defer freeCheckoutOpts(cOpts) ret := C.git_checkout_index(v.ptr, iptr, cOpts) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } @@ -226,6 +228,7 @@ func (v *Repository) CheckoutTree(tree *Tree, opts *CheckoutOpts) error { defer freeCheckoutOpts(cOpts) ret := C.git_checkout_tree(v.ptr, tree.ptr, cOpts) + runtime.KeepAlive(v) if ret < 0 { return MakeGitError(ret) } diff --git a/cherrypick.go b/cherrypick.go index afc1b7e..8983a7a 100644 --- a/cherrypick.go +++ b/cherrypick.go @@ -66,6 +66,8 @@ func (v *Repository) Cherrypick(commit *Commit, opts CherrypickOptions) error { defer freeCherrypickOpts(cOpts) ecode := C.git_cherrypick(v.ptr, commit.cast_ptr, cOpts) + runtime.KeepAlive(v) + runtime.KeepAlive(commit) if ecode < 0 { return MakeGitError(ecode) } diff --git a/commit.go b/commit.go index 3ccb5da..5aa5f25 100644 --- a/commit.go +++ b/commit.go @@ -77,7 +77,7 @@ func (c *Commit) Tree() (*Tree, error) { func (c *Commit) TreeId() *Oid { ret := newOidFromC(C.git_commit_tree_id(c.cast_ptr)) runtime.KeepAlive(c) - return c + return ret } func (c *Commit) Author() *Signature { @@ -101,15 +101,21 @@ func (c *Commit) Parent(n uint) *Commit { return nil } - return allocCommit(cobj, c.repo) + parent := allocCommit(cobj, c.repo) + runtime.KeepAlive(c) + return parent } func (c *Commit) ParentId(n uint) *Oid { - return newOidFromC(C.git_commit_parent_id(c.cast_ptr, C.uint(n))) + ret := newOidFromC(C.git_commit_parent_id(c.cast_ptr, C.uint(n))) + runtime.KeepAlive(c) + return ret } func (c *Commit) ParentCount() uint { - return uint(C.git_commit_parentcount(c.cast_ptr)) + ret := uint(C.git_commit_parentcount(c.cast_ptr)) + runtime.KeepAlive(c) + return ret } func (c *Commit) Amend(refname string, author, committer *Signature, message string, tree *Tree) (*Oid, error) { @@ -142,6 +148,9 @@ func (c *Commit) Amend(refname string, author, committer *Signature, message str oid := new(Oid) cerr := C.git_commit_amend(oid.toC(), c.cast_ptr, cref, authorSig, committerSig, nil, cmsg, tree.cast_ptr) + runtime.KeepAlive(oid) + runtime.KeepAlive(c) + runtime.KeepAlive(tree) if cerr < 0 { return nil, MakeGitError(cerr) } diff --git a/config.go b/config.go index 7408fbc..c19ad32 100644 --- a/config.go +++ b/config.go @@ -78,6 +78,7 @@ func (c *Config) AddFile(path string, level ConfigLevel, force bool) error { defer runtime.UnlockOSThread() ret := C.git_config_add_file_ondisk(c.ptr, cpath, C.git_config_level_t(level), cbool(force)) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -94,6 +95,7 @@ func (c *Config) LookupInt32(name string) (int32, error) { defer runtime.UnlockOSThread() ret := C.git_config_get_int32(&out, c.ptr, cname) + runtime.KeepAlive(c) if ret < 0 { return 0, MakeGitError(ret) } @@ -110,6 +112,7 @@ func (c *Config) LookupInt64(name string) (int64, error) { defer runtime.UnlockOSThread() ret := C.git_config_get_int64(&out, c.ptr, cname) + runtime.KeepAlive(c) if ret < 0 { return 0, MakeGitError(ret) } @@ -126,7 +129,9 @@ func (c *Config) LookupString(name string) (string, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - if ret := C.git_config_get_string_buf(&valBuf, c.ptr, cname); ret < 0 { + ret := C.git_config_get_string_buf(&valBuf, c.ptr, cname) + runtime.KeepAlive(c) + if ret < 0 { return "", MakeGitError(ret) } defer C.git_buf_free(&valBuf) @@ -143,6 +148,7 @@ func (c *Config) LookupBool(name string) (bool, error) { defer runtime.UnlockOSThread() ret := C.git_config_get_bool(&out, c.ptr, cname) + runtime.KeepAlive(c) if ret < 0 { return false, MakeGitError(ret) } @@ -162,7 +168,7 @@ func (c *Config) NewMultivarIterator(name, regexp string) (*ConfigIterator, erro defer C.free(unsafe.Pointer(cregexp)) } - iter := new(ConfigIterator) + iter := &ConfigIterator{cfg: c} runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -179,7 +185,7 @@ func (c *Config) NewMultivarIterator(name, regexp string) (*ConfigIterator, erro // NewIterator creates an iterator over each entry in the // configuration func (c *Config) NewIterator() (*ConfigIterator, error) { - iter := new(ConfigIterator) + iter := &ConfigIterator{cfg: c} runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -195,7 +201,7 @@ func (c *Config) NewIterator() (*ConfigIterator, error) { // NewIteratorGlob creates an iterator over each entry in the // configuration whose name matches the given regular expression func (c *Config) NewIteratorGlob(regexp string) (*ConfigIterator, error) { - iter := new(ConfigIterator) + iter := &ConfigIterator{cfg: c} cregexp := C.CString(regexp) defer C.free(unsafe.Pointer(cregexp)) @@ -221,6 +227,7 @@ func (c *Config) SetString(name, value string) (err error) { defer runtime.UnlockOSThread() ret := C.git_config_set_string(c.ptr, cname, cvalue) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -241,6 +248,7 @@ func (c *Config) SetInt32(name string, value int32) (err error) { defer runtime.UnlockOSThread() ret := C.git_config_set_int32(c.ptr, cname, C.int32_t(value)) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -256,6 +264,7 @@ func (c *Config) SetInt64(name string, value int64) (err error) { defer runtime.UnlockOSThread() ret := C.git_config_set_int64(c.ptr, cname, C.int64_t(value)) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -271,6 +280,7 @@ func (c *Config) SetBool(name string, value bool) (err error) { defer runtime.UnlockOSThread() ret := C.git_config_set_bool(c.ptr, cname, cbool(value)) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -292,6 +302,7 @@ func (c *Config) SetMultivar(name, regexp, value string) (err error) { defer runtime.UnlockOSThread() ret := C.git_config_set_multivar(c.ptr, cname, cregexp, cvalue) + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -307,7 +318,7 @@ func (c *Config) Delete(name string) error { defer runtime.UnlockOSThread() ret := C.git_config_delete_entry(c.ptr, cname) - + runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } @@ -323,6 +334,8 @@ func (c *Config) OpenLevel(parent *Config, level ConfigLevel) (*Config, error) { defer runtime.UnlockOSThread() ret := C.git_config_open_level(&config.ptr, parent.ptr, C.git_config_level_t(level)) + runtime.KeepAlive(c) + runtime.KeepAlive(parent) if ret < 0 { return nil, MakeGitError(ret) } @@ -349,6 +362,7 @@ func OpenOndisk(parent *Config, path string) (*Config, error) { type ConfigIterator struct { ptr *C.git_config_iterator + cfg *Config } // Next returns the next entry for this iterator @@ -363,7 +377,10 @@ func (iter *ConfigIterator) Next() (*ConfigEntry, error) { return nil, MakeGitError(ret) } - return newConfigEntryFromC(centry), nil + entry := newConfigEntryFromC(centry) + runtime.KeepAlive(iter) + + return entry, nil } func (iter *ConfigIterator) Free() { diff --git a/describe.go b/describe.go index d75dbcb..0b75076 100644 --- a/describe.go +++ b/describe.go @@ -128,6 +128,7 @@ func (c *Commit) Describe(opts *DescribeOptions) (*DescribeResult, error) { defer runtime.UnlockOSThread() ecode := C.git_describe_commit(&resultPtr, c.ptr, cDescribeOpts) + runtime.KeepAlive(c) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -162,6 +163,7 @@ func (repo *Repository) DescribeWorkdir(opts *DescribeOptions) (*DescribeResult, defer runtime.UnlockOSThread() ecode := C.git_describe_workdir(&resultPtr, repo.ptr, cDescribeOpts) + runtime.KeepAlive(repo) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -206,6 +208,7 @@ func (result *DescribeResult) Format(opts *DescribeFormatOptions) (string, error defer runtime.UnlockOSThread() ecode := C.git_describe_format(&resultBuf, result.ptr, cFormatOpts) + runtime.KeepAlive(result) if ecode < 0 { return "", MakeGitError(ecode) } diff --git a/repository.go b/repository.go index a44b9b8..44d18a9 100644 --- a/repository.go +++ b/repository.go @@ -129,6 +129,7 @@ func NewRepositoryWrapOdb(odb *Odb) (repo *Repository, err error) { func (v *Repository) SetRefdb(refdb *Refdb) { C.git_repository_set_refdb(v.ptr, refdb.ptr) + runtime.KeepAlive(v) } func (v *Repository) Free() { @@ -143,6 +144,7 @@ func (v *Repository) Config() (*Config, error) { defer runtime.UnlockOSThread() ret := C.git_repository_config(&config.ptr, v.ptr) + runtime.KeepAlive(v) if ret < 0 { return nil, MakeGitError(ret) } @@ -158,6 +160,7 @@ 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) } @@ -172,6 +175,7 @@ func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) { defer runtime.UnlockOSThread() ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t)) + runtime.KeepAlive(id) if ret < 0 { return nil, MakeGitError(ret) } @@ -241,6 +245,7 @@ func (v *Repository) SetHead(refname string) error { defer runtime.UnlockOSThread() ecode := C.git_repository_set_head(v.ptr, cname) + runtime.KeepAlive(v) if ecode != 0 { return MakeGitError(ecode) } @@ -252,6 +257,8 @@ func (v *Repository) SetHeadDetached(id *Oid) error { defer runtime.UnlockOSThread() ecode := C.git_repository_set_head_detached(v.ptr, id.toC()) + runtime.KeepAlive(v) + runtime.KeepAlive(id) if ecode != 0 { return MakeGitError(ecode) } @@ -263,6 +270,7 @@ func (v *Repository) IsHeadDetached() (bool, error) { defer runtime.UnlockOSThread() ret := C.git_repository_head_detached(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return false, MakeGitError(ret) } @@ -275,6 +283,7 @@ func (v *Repository) IsHeadUnborn() (bool, error) { defer runtime.UnlockOSThread() ret := C.git_repository_head_unborn(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return false, MakeGitError(ret) } @@ -286,6 +295,7 @@ func (v *Repository) IsEmpty() (bool, error) { defer runtime.UnlockOSThread() ret := C.git_repository_is_empty(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return false, MakeGitError(ret) } @@ -298,6 +308,7 @@ func (v *Repository) IsShallow() (bool, error) { defer runtime.UnlockOSThread() ret := C.git_repository_is_shallow(v.ptr) + runtime.KeepAlive(v) if ret < 0 { return false, MakeGitError(ret) } @@ -368,6 +379,9 @@ func (v *Repository) CreateCommit( authorSig, committerSig, nil, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg) + runtime.KeepAlive(v) + runtime.KeepAlive(oid) + runtime.KeepAlive(parents) if ret < 0 { return nil, MakeGitError(ret) } @@ -391,7 +405,9 @@ func (v *Repository) Odb() (odb *Odb, err error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 { + ret := C.git_repository_odb(&odb.ptr, v.ptr) + runtime.KeepAlive(v) + if ret < 0 { return nil, MakeGitError(ret) } @@ -400,15 +416,21 @@ func (v *Repository) Odb() (odb *Odb, err error) { } func (repo *Repository) Path() string { - return C.GoString(C.git_repository_path(repo.ptr)) + s := C.GoString(C.git_repository_path(repo.ptr)) + runtime.KeepAlive(repo) + return s } func (repo *Repository) IsBare() bool { - return C.git_repository_is_bare(repo.ptr) != 0 + ret := C.git_repository_is_bare(repo.ptr) != 0 + runtime.KeepAlive(repo) + return ret } func (repo *Repository) Workdir() string { - return C.GoString(C.git_repository_workdir(repo.ptr)) + s := C.GoString(C.git_repository_workdir(repo.ptr)) + runtime.KeepAlive(repo) + return s } func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error { @@ -421,6 +443,7 @@ func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error { if ret := C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)); ret < 0 { return MakeGitError(ret) } + runtime.KeepAlive(repo) return nil } @@ -434,6 +457,7 @@ func (v *Repository) TreeBuilder() (*TreeBuilder, error) { if ret := C.git_treebuilder_new(&bld.ptr, v.ptr, nil); ret < 0 { return nil, MakeGitError(ret) } + runtime.SetFinalizer(bld, (*TreeBuilder).Free) bld.repo = v @@ -474,7 +498,10 @@ func (r *Repository) State() RepositoryState { runtime.LockOSThread() defer runtime.UnlockOSThread() - return RepositoryState(C.git_repository_state(r.ptr)) + ret := RepositoryState(C.git_repository_state(r.ptr)) + runtime.KeepAlive(r) + + return ret } func (r *Repository) StateCleanup() error { @@ -482,18 +509,22 @@ func (r *Repository) StateCleanup() error { defer runtime.UnlockOSThread() cErr := C.git_repository_state_cleanup(r.ptr) + runtime.KeepAlive(r) if cErr < 0 { return MakeGitError(cErr) } return nil } + func (r *Repository) AddGitIgnoreRules(rules string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() crules := C.CString(rules) defer C.free(unsafe.Pointer(crules)) - if ret := C.git_ignore_add_rule(r.ptr, crules); ret < 0 { + ret := C.git_ignore_add_rule(r.ptr, crules) + runtime.KeepAlive(r) + if ret < 0 { return MakeGitError(ret) } return nil @@ -503,7 +534,9 @@ func (r *Repository) ClearGitIgnoreRules() error { runtime.LockOSThread() defer runtime.UnlockOSThread() - if ret := C.git_ignore_clear_internal_rules(r.ptr); ret < 0 { + ret := C.git_ignore_clear_internal_rules(r.ptr) + runtime.KeepAlive(r) + if ret < 0 { return MakeGitError(ret) } return nil -- cgit v1.2.3