Free Git objects via finalizers or manually

Provide a manual way of freeing objects, but set finalizers for them
in case the user does not want to worry about memory management, which
would be useful for commits or trees, which sare typically small.

When the objects are freed manually, the finalizer is unset to avoid
double-freeing, mimicking what the go runtime does.
This commit is contained in:
Carlos Martín Nieto 2013-03-06 01:43:48 +01:00
parent 2885e3fe0c
commit d43561fbf7
5 changed files with 26 additions and 13 deletions

View File

@ -7,6 +7,7 @@ package git
*/
import "C"
import (
"runtime"
"unsafe"
)
@ -14,8 +15,9 @@ type Blob struct {
ptr *C.git_object
}
func freeBlob(blob *Blob) {
C.git_object_free(blob.ptr)
func (v *Blob) Free() {
runtime.SetFinalizer(v, nil)
C.git_object_free(v.ptr)
}
func (v *Blob) Contents() []byte {

View File

@ -9,6 +9,7 @@ extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
import "C"
import (
"runtime"
"time"
)
@ -32,6 +33,8 @@ func (c *Commit) Tree() (*Tree, error) {
if err < 0 {
return nil, LastError()
}
runtime.SetFinalizer(tree, (*Tree).Free)
return tree, nil
}

7
odb.go
View File

@ -49,7 +49,7 @@ func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
return nil, LastError()
}
runtime.SetFinalizer(obj, freeOdbObject)
runtime.SetFinalizer(obj, (*OdbObject).Free)
return
}
@ -57,8 +57,9 @@ type OdbObject struct {
ptr *C.git_odb_object
}
func freeOdbObject(obj *OdbObject) {
C.git_odb_object_free(obj.ptr)
func (v *OdbObject) Free() {
runtime.SetFinalizer(v, nil)
C.git_odb_object_free(v.ptr)
}
func (v *OdbObject) Type() int {

View File

@ -27,7 +27,7 @@ func Open(path string) (*Repository, error) {
return nil, LastError()
}
runtime.SetFinalizer(repo, freeRepository)
runtime.SetFinalizer(repo, (*Repository).Free)
return repo, nil
}
@ -42,12 +42,13 @@ func Init(path string, isbare bool) (*Repository, error) {
return nil, LastError()
}
runtime.SetFinalizer(repo, freeRepository)
runtime.SetFinalizer(repo, (*Repository).Free)
return repo, nil
}
func freeRepository(repo *Repository) {
C.git_repository_free(repo.ptr)
func (v *Repository) Free() {
runtime.SetFinalizer(v, nil)
C.git_repository_free(v.ptr)
}
func (v *Repository) Config() (*Config, error) {
@ -127,8 +128,9 @@ func (v *Repository) Commit(
}
*/
func freeOdb(odb *Odb) {
C.git_odb_free(odb.ptr)
func (v *Odb) Free() {
runtime.SetFinalizer(v, nil)
C.git_odb_free(v.ptr)
}
func (v *Repository) Odb() (odb *Odb, err error) {
@ -137,7 +139,7 @@ func (v *Repository) Odb() (odb *Odb, err error) {
return nil, LastError()
}
runtime.SetFinalizer(odb, freeOdb)
runtime.SetFinalizer(odb, (*Odb).Free)
return
}

View File

@ -9,6 +9,7 @@ extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
import "C"
import (
"runtime"
"unsafe"
)
@ -31,6 +32,7 @@ func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
}
func (t *Tree) Free() {
runtime.SetFinalizer(t, nil)
C.git_tree_free(t.ptr)
}
@ -40,6 +42,8 @@ func TreeLookup(repo *Repository, oid *Oid) (*Tree, error) {
if err < 0 {
return nil, LastError()
}
runtime.SetFinalizer(tree, (*Tree).Free)
return tree, nil
}
@ -99,7 +103,8 @@ type TreeBuilder struct {
repo *Repository
}
func freeTreeBuilder(v *TreeBuilder) {
func (v *TreeBuilder) Free() {
runtime.SetFinalizer(v, nil)
C.git_treebuilder_free(v.ptr)
}