diff options
| author | Russ Cox <rsc@golang.org> | 2010-02-08 21:41:54 -0800 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-02-08 21:41:54 -0800 |
| commit | 4227e0fcd8ab454433d9c3d94da6eae68dfc1689 (patch) | |
| tree | 97dc24869f546fd7032625f3b2159ab8afbd1000 /src/pkg/runtime/malloc.cgo | |
| parent | 572ffc76eca67ff28370cb29fc76ebcbe2aeb8cd (diff) | |
| download | golang-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.cgo | 18 |
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); } |
