summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/cgocall.c
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:29:06 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:29:06 +0100
commitcc71238f4c5d23ee2ebffd0d6c307e308ea163c1 (patch)
treedd0b57254871fac715258385f5485ba136d6b62a /src/pkg/runtime/cgocall.c
parentb32e37d71adab0e2a2b7c4433e7bad169a9a4f98 (diff)
parentb39e15dde5ec7b96c15da9faf4ab5892501c1aae (diff)
downloadgolang-cc71238f4c5d23ee2ebffd0d6c307e308ea163c1.tar.gz
Merge tag 'upstream/1.1_hg20130323' into debian-sid
Upstream version 1.1~hg20130323
Diffstat (limited to 'src/pkg/runtime/cgocall.c')
-rw-r--r--src/pkg/runtime/cgocall.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/pkg/runtime/cgocall.c b/src/pkg/runtime/cgocall.c
index 590bf9b67..0c9618749 100644
--- a/src/pkg/runtime/cgocall.c
+++ b/src/pkg/runtime/cgocall.c
@@ -95,7 +95,8 @@ static void unwindm(void);
// Call from Go to C.
-static FuncVal unlockOSThread = { runtime·unlockOSThread };
+static void endcgo(void);
+static FuncVal endcgoV = { endcgo };
void
runtime·cgocall(void (*fn)(void*), void *arg)
@@ -123,7 +124,7 @@ runtime·cgocall(void (*fn)(void*), void *arg)
* cgo callback. Add entry to defer stack in case of panic.
*/
runtime·lockOSThread();
- d.fn = &unlockOSThread;
+ d.fn = &endcgoV;
d.siz = 0;
d.link = g->defer;
d.argp = (void*)-1; // unused because unlockm never recovers
@@ -148,6 +149,16 @@ runtime·cgocall(void (*fn)(void*), void *arg)
runtime·asmcgocall(fn, arg);
runtime·exitsyscall();
+ if(g->defer != &d || d.fn != &endcgoV)
+ runtime·throw("runtime: bad defer entry in cgocallback");
+ g->defer = d.link;
+ endcgo();
+}
+
+static void
+endcgo(void)
+{
+ runtime·unlockOSThread();
m->ncgo--;
if(m->ncgo == 0) {
// We are going back to Go and are not in a recursive
@@ -156,11 +167,6 @@ runtime·cgocall(void (*fn)(void*), void *arg)
m->cgomal = nil;
}
- if(g->defer != &d || d.fn != &unlockOSThread)
- runtime·throw("runtime: bad defer entry in cgocallback");
- g->defer = d.link;
- runtime·unlockOSThread();
-
if(raceenabled)
runtime·raceacquire(&cgosync);
}
@@ -280,3 +286,9 @@ runtime·cgounimpl(void) // called from (incomplete) assembly
{
runtime·throw("runtime: cgo not implemented");
}
+
+// For cgo-using programs with external linking,
+// export "main" (defined in assembly) so that libc can handle basic
+// C runtime startup and call the Go program as if it were
+// the C main function.
+#pragma cgo_export_static main