summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.cgo
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-02-08 21:41:54 -0800
committerRuss Cox <rsc@golang.org>2010-02-08 21:41:54 -0800
commit4227e0fcd8ab454433d9c3d94da6eae68dfc1689 (patch)
tree97dc24869f546fd7032625f3b2159ab8afbd1000 /src/pkg/runtime/malloc.cgo
parent572ffc76eca67ff28370cb29fc76ebcbe2aeb8cd (diff)
downloadgolang-4227e0fcd8ab454433d9c3d94da6eae68dfc1689.tar.gz
runtime: allow arbitrary return type in SetFinalizer.
finalize chan, to free OS X semaphore inside Lock. os: finalize File, to close fd. Fixes issue 503. R=ken2 CC=golang-dev http://codereview.appspot.com/204065
Diffstat (limited to 'src/pkg/runtime/malloc.cgo')
-rw-r--r--src/pkg/runtime/malloc.cgo18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/pkg/runtime/malloc.cgo b/src/pkg/runtime/malloc.cgo
index 286aa2bf3..c6d5c6e33 100644
--- a/src/pkg/runtime/malloc.cgo
+++ b/src/pkg/runtime/malloc.cgo
@@ -289,6 +289,8 @@ func SetFinalizer(obj Eface, finalizer Eface) {
byte *base;
uintptr size;
FuncType *ft;
+ int32 i, nret;
+ Type *t;
if(obj.type == nil) {
printf("runtime.SetFinalizer: first argument is nil interface\n");
@@ -303,6 +305,7 @@ func SetFinalizer(obj Eface, finalizer Eface) {
printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
goto throw;
}
+ nret = 0;
if(finalizer.type != nil) {
if(finalizer.type->kind != KindFunc) {
badfunc:
@@ -310,12 +313,21 @@ func SetFinalizer(obj Eface, finalizer Eface) {
goto throw;
}
ft = (FuncType*)finalizer.type;
- if(ft->dotdotdot || ft->out.len != 0 || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
+ if(ft->dotdotdot || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
goto badfunc;
- if(getfinalizer(obj.data, 0)) {
+
+ // compute size needed for return parameters
+ for(i=0; i<ft->out.len; i++) {
+ t = ((Type**)ft->out.array)[i];
+ nret = (nret + t->align - 1) & ~(t->align - 1);
+ nret += t->size;
+ }
+ nret = (nret + sizeof(void*)-1) & ~(sizeof(void*)-1);
+
+ if(getfinalizer(obj.data, 0, nil)) {
printf("runtime.SetFinalizer: finalizer already set");
goto throw;
}
}
- addfinalizer(obj.data, finalizer.data);
+ addfinalizer(obj.data, finalizer.data, nret);
}