void runtime·cgocallbackg(void) { if(g != m->curg) { runtime·prints("runtime: bad g in cgocallback"); runtime·exit(2); } runtime·exitsyscall(); // coming out of cgo call runtime·cgocallbackg1(); runtime·entersyscall(); // going back to cgo call }
void runtime·cgocallbackg(void) { if(g != m->curg) { runtime·prints("runtime: bad g in cgocallback"); runtime·exit(2); } if(m->racecall) { // We were not in syscall, so no need to call runtime·exitsyscall. // However we must set m->locks for the following reason. // Race detector runtime makes __tsan_symbolize cgo callback // holding internal mutexes. The mutexes are not cooperative with Go scheduler. // So if we deschedule a goroutine that holds race detector internal mutex // (e.g. preempt it), another goroutine will deadlock trying to acquire the same mutex. m->locks++; runtime·cgocallbackg1(); m->locks--; } else { runtime·exitsyscall(); // coming out of cgo call runtime·cgocallbackg1(); runtime·entersyscall(); // going back to cgo call } }