From d43561fbf711896f5ce33f409c6000946416a82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 6 Mar 2013 01:43:48 +0100 Subject: [PATCH] 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. --- blob.go | 6 ++++-- commit.go | 3 +++ odb.go | 7 ++++--- repository.go | 16 +++++++++------- tree.go | 7 ++++++- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/blob.go b/blob.go index 91064b1..f7db15e 100644 --- a/blob.go +++ b/blob.go @@ -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 { diff --git a/commit.go b/commit.go index 855ed87..779ebd7 100644 --- a/commit.go +++ b/commit.go @@ -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 } diff --git a/odb.go b/odb.go index 5688080..6370999 100644 --- a/odb.go +++ b/odb.go @@ -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 { diff --git a/repository.go b/repository.go index 755926e..bfbfebd 100644 --- a/repository.go +++ b/repository.go @@ -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 } diff --git a/tree.go b/tree.go index 324fc1f..6f1f2d0 100644 --- a/tree.go +++ b/tree.go @@ -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) }