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 "C"
import ( import (
"runtime"
"unsafe" "unsafe"
) )
@ -14,8 +15,9 @@ type Blob struct {
ptr *C.git_object ptr *C.git_object
} }
func freeBlob(blob *Blob) { func (v *Blob) Free() {
C.git_object_free(blob.ptr) runtime.SetFinalizer(v, nil)
C.git_object_free(v.ptr)
} }
func (v *Blob) Contents() []byte { 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 "C"
import ( import (
"runtime"
"time" "time"
) )
@ -32,6 +33,8 @@ func (c *Commit) Tree() (*Tree, error) {
if err < 0 { if err < 0 {
return nil, LastError() return nil, LastError()
} }
runtime.SetFinalizer(tree, (*Tree).Free)
return tree, nil 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() return nil, LastError()
} }
runtime.SetFinalizer(obj, freeOdbObject) runtime.SetFinalizer(obj, (*OdbObject).Free)
return return
} }
@ -57,8 +57,9 @@ type OdbObject struct {
ptr *C.git_odb_object ptr *C.git_odb_object
} }
func freeOdbObject(obj *OdbObject) { func (v *OdbObject) Free() {
C.git_odb_object_free(obj.ptr) runtime.SetFinalizer(v, nil)
C.git_odb_object_free(v.ptr)
} }
func (v *OdbObject) Type() int { func (v *OdbObject) Type() int {

View File

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

View File

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