mirror of
https://github.com/golang/go
synced 2024-11-21 20:54:45 -07:00
runtime: do not garbage collect windows callbacks
Fixes #1883. Fixes #1702. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4532103
This commit is contained in:
parent
119a341c38
commit
b873701dbd
@ -324,13 +324,31 @@ runtime·ctrlhandler1(uint32 type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Will keep all callbacks in a linked list, so they don't get garbage collected.
|
||||||
|
typedef struct Callback Callback;
|
||||||
|
struct Callback {
|
||||||
|
Callback* link;
|
||||||
|
void* gobody;
|
||||||
|
byte asmbody;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Callbacks Callbacks;
|
||||||
|
struct Callbacks {
|
||||||
|
Lock;
|
||||||
|
Callback* link;
|
||||||
|
int32 n;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Callbacks cbs;
|
||||||
|
|
||||||
// Call back from windows dll into go.
|
// Call back from windows dll into go.
|
||||||
byte *
|
byte *
|
||||||
runtime·compilecallback(Eface fn, bool cleanstack)
|
runtime·compilecallback(Eface fn, bool cleanstack)
|
||||||
{
|
{
|
||||||
Func *f;
|
Func *f;
|
||||||
int32 argsize, n;
|
int32 argsize, n;
|
||||||
byte *ret, *p;
|
byte *p;
|
||||||
|
Callback *c;
|
||||||
|
|
||||||
if(fn.type->kind != KindFunc)
|
if(fn.type->kind != KindFunc)
|
||||||
runtime·panicstring("not a function");
|
runtime·panicstring("not a function");
|
||||||
@ -348,7 +366,23 @@ runtime·compilecallback(Eface fn, bool cleanstack)
|
|||||||
if(cleanstack)
|
if(cleanstack)
|
||||||
n += 2; // ... argsize
|
n += 2; // ... argsize
|
||||||
|
|
||||||
ret = p = runtime·mal(n);
|
runtime·lock(&cbs);
|
||||||
|
for(c = cbs.link; c != nil; c = c->link) {
|
||||||
|
if(c->gobody == fn.data) {
|
||||||
|
runtime·unlock(&cbs);
|
||||||
|
return &c->asmbody;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cbs.n >= 20)
|
||||||
|
runtime·throw("too many callback functions");
|
||||||
|
c = runtime·mal(sizeof *c + n);
|
||||||
|
c->gobody = fn.data;
|
||||||
|
c->link = cbs.link;
|
||||||
|
cbs.link = c;
|
||||||
|
cbs.n++;
|
||||||
|
runtime·unlock(&cbs);
|
||||||
|
|
||||||
|
p = &c->asmbody;
|
||||||
|
|
||||||
// MOVL fn, AX
|
// MOVL fn, AX
|
||||||
*p++ = 0xb8;
|
*p++ = 0xb8;
|
||||||
@ -376,7 +410,7 @@ runtime·compilecallback(Eface fn, bool cleanstack)
|
|||||||
} else
|
} else
|
||||||
*p = 0xc3;
|
*p = 0xc3;
|
||||||
|
|
||||||
return ret;
|
return &c->asmbody;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user