Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: windows callback on non-Go thread fails #6751

Closed
alexbrainman opened this issue Nov 12, 2013 · 34 comments
Closed

runtime: windows callback on non-Go thread fails #6751

alexbrainman opened this issue Nov 12, 2013 · 34 comments
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@alexbrainman
Copy link
Member

This test

diff --git a/src/pkg/runtime/syscall_windows_test.go
b/src/pkg/runtime/syscall_windows_test.go
--- a/src/pkg/runtime/syscall_windows_test.go
+++ b/src/pkg/runtime/syscall_windows_test.go
@@ -240,5 +240,35 @@
 }
 
 func TestCallbackInAnotherThread(t *testing.T) {
-   // TODO: test a function which calls back in another thread: QueueUserAPC() or
CreateThread()
+   d := GetDLL(t, "kernel32.dll")
+
+   f := func(p uintptr) uintptr {
+       return p
+   }
+   r, _, err := d.Proc("CreateThread").Call(0, 0, syscall.NewCallback(f), 123,
0, 0)
+   if r == 0 {
+       t.Fatalf("CreateThread failed: %v", err)
+   }
+   h := syscall.Handle(r)
+   defer syscall.CloseHandle(h)
+
+   switch s, err := syscall.WaitForSingleObject(h, 100); s {
+   case syscall.WAIT_OBJECT_0:
+       break
+   case syscall.WAIT_TIMEOUT:
+       t.Fatal("timeout waiting for thread to exit")
+   case syscall.WAIT_FAILED:
+       t.Fatalf("WaitForSingleObject failed: %v", err)
+   default:
+       t.Fatalf("WaitForSingleObject returns unexpected value %v", s)
+   }
+
+   var ec uint32
+   r, _, err = d.Proc("GetExitCodeThread").Call(uintptr(h),
uintptr(unsafe.Pointer(&ec)))
+   if r == 0 {
+       t.Fatalf("GetExitCodeThread failed: %v", err)
+   }
+   if ec != 123 {
+       t.Fatalf("expected 123, but got %d", ec)
+   }
 }

fails with

C:\>u:\test -test.v -test.run=Another
=== RUN TestCallbackInAnotherThread
--- FAIL: TestCallbackInAnotherThread (0.11 seconds)
        syscall_windows_test.go:259: timeout waiting for thread to exit
FAIL

hg id is 39c724dd7f25

Alex

PS: for after Go 1.2
@alexbrainman
Copy link
Member Author

Comment 1:

The issue is raised here
https://groups.google.com/d/topic/golang-nuts/h91eDx27vrQ/discussion
Alex

@gopherbot
Copy link

Comment 2 by vanillabluesky007:

Looks great. 
Probably the same issue that i triggered. The only difference in my case is that my dll
uses C-Runtime therefore creates threads with _beginthreadex rather than CreateThread.
(different thread management in both)
See:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx 
 
(P.s nice trick calling kernel32.dll directly and apologies for being late on opening
the issue!)
/Sven

@alexbrainman
Copy link
Member Author

Comment 3:

sven,
Attaching your test case here for posterity. I could not use your dll, it uses
msvcr110d.dll that I don't have on my amd64 pc. And I couldn't build it on my 386 pc,
because _beginthread expects __cdecl, not __stdcall function (it, probably, didn't
matter for you, if you're on amd64).
Anyway, I think my test is good enough for our purpose. Don't you agree?
I investigated where my test hangs. It is in lockextra, like you said. And it is because
no free m. cgo does not have that problem, because it sets runtime·needextram to 1 at
the start. I don't know why it is limited to cgo only. But if I move it into runtime,
then my test PASSes. I suspect your program should work too.
Here is my diff:
diff --git a/src/pkg/runtime/cgo/iscgo.c b/src/pkg/runtime/cgo/iscgo.c
--- a/src/pkg/runtime/cgo/iscgo.c
+++ b/src/pkg/runtime/cgo/iscgo.c
@@ -12,4 +12,3 @@
 #include "../runtime.h"
 
 bool runtime·iscgo = 1;
-uint32 runtime·needextram = 1;  // create an extra M on first cgo call
diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go
--- a/src/pkg/runtime/crash_test.go
+++ b/src/pkg/runtime/crash_test.go
@@ -105,7 +105,7 @@
    testDeadlock(t, lockedDeadlockSource)
 }
 
-func TestLockedDeadlock2(t *testing.T) {
+func testLockedDeadlock2(t *testing.T) {
    testDeadlock(t, lockedDeadlockSource2)
 }
 
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -64,7 +64,7 @@
 
 Sched  runtime·sched;
 int32  runtime·gomaxprocs;
-uint32 runtime·needextram;
+uint32 runtime·needextram = 1;
 bool   runtime·iscgo;
 M  runtime·m0;
 G  runtime·g0;     // idle goroutine for m0
diff --git a/src/pkg/runtime/syscall_windows_test.go
b/src/pkg/runtime/syscall_windows_test.go
--- a/src/pkg/runtime/syscall_windows_test.go
+++ b/src/pkg/runtime/syscall_windows_test.go
@@ -240,5 +240,35 @@
 }
 
 func TestCallbackInAnotherThread(t *testing.T) {
-   // TODO: test a function which calls back in another thread: QueueUserAPC() or
CreateThread()
+   d := GetDLL(t, "kernel32.dll")
+
+   f := func(p uintptr) uintptr {
+       return p
+   }
+   r, _, err := d.Proc("CreateThread").Call(0, 0, syscall.NewCallback(f), 123, 0, 0)
+   if r == 0 {
+       t.Fatalf("CreateThread failed: %v", err)
+   }
+   h := syscall.Handle(r)
+   defer syscall.CloseHandle(h)
+
+   switch s, err := syscall.WaitForSingleObject(h, 100); s {
+   case syscall.WAIT_OBJECT_0:
+       break
+   case syscall.WAIT_TIMEOUT:
+       t.Fatal("timeout waiting for thread to exit")
+   case syscall.WAIT_FAILED:
+       t.Fatalf("WaitForSingleObject failed: %v", err)
+   default:
+       t.Fatalf("WaitForSingleObject returns unexpected value %v", s)
+   }
+
+   var ec uint32
+   r, _, err = d.Proc("GetExitCodeThread").Call(uintptr(h), uintptr(unsafe.Pointer(&ec)))
+   if r == 0 {
+       t.Fatalf("GetExitCodeThread failed: %v", err)
+   }
+   if ec != 123 {
+       t.Fatalf("expected 123, but got %d", ec)
+   }
 }
I had to disable one test. I don't know why, so we have to resolve that.
We cannot make changes now, not until after Go 1.2 is released. Perhaps this change will
get accepted. I hope you can use this in the meantime to fix your problem locally.
Alex

Attachments:

  1. multithread.go (1138 bytes)
  2. multithreaded.zip (6031 bytes)

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 4:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 5:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 6:

Labels changed: added repo-main.

@chowey
Copy link

chowey commented Nov 17, 2014

Comment 7:

This one bit me today.
import "C" does solve the issue. What is the status on merging this into the main trunk
of Go?

@alexbrainman
Copy link
Member Author

Comment 8:

cameron.howey,
My patch at #3 is not good. Like I said there: "... I had to disable one test. I don't
know why, so we have to resolve that. ...". It appears the test fails with "deadlock"
message, so we need to rearrange scheduler somewhat before we can apply this patch.
I didn't push for it, because I don't have anyone complaining about it. Perhaps, if it
is important to you, you could tell us what your difficulty is. Maybe that will convince
someone to put some actual effort into it. Thank you.
Alex

@chowey
Copy link

chowey commented Nov 27, 2014

Comment 9:

I wanted to use Windows COM (specifically the MMDevice and EndpointVolume APIs) from a
Go project. If this sounds like a bad idea, it is. So I wrote a simple DLL in C++ for
the COM stuff and exported the relevant functions. I have the DLL start another thread
and run the COM stuff from there, to avoid worrying about how COM was going to interact
with Go's thread-hopping, etc.
I use IAudioEndpointVolume::RegisterEndpointNotificationCallback to get notifications
when the system volume changes. I wanted to use a Go callback here.
So the issue is that the DLL runs a separate thread but needs to use a Go callback in
that thread. I was not otherwise using Cgo, instead using syscall to call my DLL.
Like I said, using import "C" solved the issue. It works like a champ. But I spent some
hours trying to figure it out beforehand (the Go executable just crashed with no
message) until I found this on the issue tracker.
Possibly you don't hear about this issue much because most Go programmers don't use
callbacks in a separate thread in a DLL on Windows. Furthermore, people who ARE doing
this might already use import "C", which would hide the problem.

@alexbrainman
Copy link
Member Author

Comment 10:

cameron.howey,
> I wanted to use Windows COM (specifically the MMDevice and EndpointVolume APIs) from a
Go project. If this sounds like a bad idea, it is. So I wrote a simple DLL in C++ for
the COM stuff and exported the relevant functions. ...
I would like to see what you are trying to do. You can provide a C program, if you like.
I am interested to see, if I can convert it into pure Go. Just for fun. When I have
time. Thank you.
Alex

@chowey
Copy link

chowey commented Nov 27, 2014

Comment 11:

I posted a gist: https://gist.github.com/chowey/6705c5c6b07399e6a73a

@alexbrainman
Copy link
Member Author

Comment 12:

Thank you for the gist.
Alex

@alexbrainman
Copy link
Member Author

@rsc suggestion made in #9240 of always enabling "C" under Windows seems reasonable, if its an option.

Importing "C" package makes your program use Cgo. So your approach does not seems reasonable to me personally.

Alex

@billziss-gh
Copy link
Contributor

billziss-gh commented May 22, 2018

Are there any plans to fix this problem?

My specific need is the following: I have cgofuse, a cross-platform FUSE (Filesystem in Userspace) package based on cgo. I am hoping to eliminate the need for cgo on Windows, by using syscall.DLL, syscall.Proc and syscall.NewCallbackCDecl, but I am blocked by this issue.

This is to support the go-ipfs project, which would rather avoid the use of a C compiler on Windows.

More information here: ipfs/kubo#5003 (comment)

Ping @djdv.

@djdv
Copy link
Contributor

djdv commented May 22, 2018

It may be worth mentioning that my original intention was to write a dynamic binding for winfsp separate from cgofuse. This issue prevents either effort from progressing.

@zhangyoufu
Copy link
Contributor

@djdv try import _ "runtime/cgo" as a workaround

@billziss-gh
Copy link
Contributor

@zhangyoufu

> set CGO_ENABLED=0

> go version
go version go1.10 windows/amd64

> go build ./examples/memfs
# github.com/billziss-gh/cgofuse/examples/memfs
_cgo_init: relocation target x_cgo_init not defined
_cgo_notify_runtime_init_done: relocation target x_cgo_notify_runtime_init_done not defined
_cgo_thread_start: relocation target x_cgo_thread_start not defined
runtime.cgo_yield: relocation target _cgo_yield not defined
_cgo_init: undefined: "x_cgo_init"
_cgo_notify_runtime_init_done: undefined: "x_cgo_notify_runtime_init_done"
_cgo_thread_start: undefined: "x_cgo_thread_start"
runtime.cgo_yield: undefined: "_cgo_yield"

@alexbrainman
Copy link
Member Author

Are there any plans to fix this problem?

There is no one working on this. If you want this fixed, I suggest you try and fix it yourself. This issue has a test, so all you need to do is adjust runtime package to make test pass. :-) If you need any help, just ask here. We will try and answer any questions you might have.

Alex

@billziss-gh
Copy link
Contributor

@alexbrainman thanks. It is unlikely I will have the time to look into this for a few days, but I am hoping to find some time for experimentation in the near future.

@billziss-gh
Copy link
Contributor

billziss-gh commented May 24, 2018

Despite my earlier statement about needing a few days to look into this I decided to have a look, but have already hit a snag.

Running all.bat hangs the whole OS(!). This happens against both the GitHub tip and the source code included with the Go 1.10 Windows distribution. This is without having applied any patches.

I have traced this problem to the following 2 tests: TestBreakpoint and TestAbort. If those tests are removed the runtime tests pass.

The OS is Windows 10.0.14393 inside VirtualBox. When the hang happens the OS becomes completely unresponsive and even after waiting an extended period of time it does not come back. The OS does not appear to bug check (no MEMORY.DMP). The Activity Monitor on my Mac host shows ~200% of CPU used by VirtualBox (I have 2 CPU's for the Windows VM).

@billziss-gh
Copy link
Contributor

The patch below appears to resolve this issue. The patch includes a simple fix in mstartm0 and needm and also adds the TestCallbackInAnotherThread from @alexbrainman's post above, which passes.

Unfortunately the patch fails multiple deadlock tests: TestSimpleDeadlock, TestInitDeadlock, TestLockedDeadlock, etc. These tests expect to see the message: "fatal error: all goroutines are asleep - deadlock!", which is printed by checkdead. Checkdead never prints this message.

I suspect the reason is that checkdead finds the extra M that we added in mstartm0 and thinks that there is no deadlock. I would appreciate any hints to overcome this difficulty.

(Please note that until a couple of hours ago I had no idea about G's, M's and P's, so I may be way off in my analysis. The following link helped me get a quick high-level understanding.)

Here is the patch:

diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index ba76f7c3e7..14944da81f 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1287,7 +1287,7 @@ func mstart1() {
 //go:yeswritebarrierrec
 func mstartm0() {
 	// Create an extra M for callbacks on threads not created by Go.
-	if iscgo && !cgoHasExtraM {
+	if (iscgo || GOOS == "windows") && !cgoHasExtraM {
 		cgoHasExtraM = true
 		newextram()
 	}
@@ -1612,7 +1612,7 @@ func allocm(_p_ *p, fn func()) *m {
 // put the m back on the list.
 //go:nosplit
 func needm(x byte) {
-	if iscgo && !cgoHasExtraM {
+	if (iscgo || GOOS == "windows") && !cgoHasExtraM {
 		// Can happen if C/C++ code calls Go from a global ctor.
 		// Can not throw, because scheduler is not initialized yet.
 		write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback)))
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index dfde12a211..fd5ecca03d 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -251,7 +251,34 @@ func TestBlockingCallback(t *testing.T) {
 }
 
 func TestCallbackInAnotherThread(t *testing.T) {
-	// TODO: test a function which calls back in another thread: QueueUserAPC() or CreateThread()
+	d := GetDLL(t, "kernel32.dll")
+	f := func(p uintptr) uintptr {
+		return p
+	}
+	r, _, err := d.Proc("CreateThread").Call(0, 0, syscall.NewCallback(f), 123, 0, 0)
+	if r == 0 {
+		t.Fatalf("CreateThread failed: %v", err)
+	}
+	h := syscall.Handle(r)
+	defer syscall.CloseHandle(h)
+	switch s, err := syscall.WaitForSingleObject(h, 100); s {
+	case syscall.WAIT_OBJECT_0:
+		break
+	case syscall.WAIT_TIMEOUT:
+		t.Fatal("timeout waiting for thread to exit")
+	case syscall.WAIT_FAILED:
+		t.Fatalf("WaitForSingleObject failed: %v", err)
+	default:
+		t.Fatalf("WaitForSingleObject returns unexpected value %v", s)
+	}
+	var ec uint32
+	r, _, err = d.Proc("GetExitCodeThread").Call(uintptr(h), uintptr(unsafe.Pointer(&ec)))
+	if r == 0 {
+		t.Fatalf("GetExitCodeThread failed: %v", err)
+	}
+	if ec != 123 {
+		t.Fatalf("expected 123, but got %d", ec)
+	}
 }
 
 type cbDLLFunc int // int determines number of callback parameters

@billziss-gh
Copy link
Contributor

billziss-gh commented May 24, 2018

Actually this problem appears to happen with cgo as well.

Consider the following go program:

package main

func main() {
	select {}
}

Run it to find that checkdead works:

$ go run deadlock.go 
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select (no cases)]:
main.main()
	/Users/billziss/Projects/go/src/deadlock.go:4 +0x20
exit status 2

Now consider the following cgo program:

package main

import "C"

func main() {
	select {}
}

Run it to find that checkdead does not work and the program hangs:

$ go run deadlock.go 
^Csignal: interrupt

I believe that the problem lies with checkdead, which should be improved to handle the extra M in cgo and the patch above.

EDIT: this latest test was done on a Mac with stock Go 1.10.

@billziss-gh
Copy link
Contributor

The following patch passes all tests on Windows and macOS. (On Windows this excludes the 2 tests TestBreakpoint and TestAbort which freeze my Windows VM, even when the patch is not applied.)

diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index ba76f7c3e7..1647044f36 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1287,7 +1287,7 @@ func mstart1() {
 //go:yeswritebarrierrec
 func mstartm0() {
 	// Create an extra M for callbacks on threads not created by Go.
-	if iscgo && !cgoHasExtraM {
+	if (iscgo || GOOS == "windows") && !cgoHasExtraM {
 		cgoHasExtraM = true
 		newextram()
 	}
@@ -1612,7 +1612,7 @@ func allocm(_p_ *p, fn func()) *m {
 // put the m back on the list.
 //go:nosplit
 func needm(x byte) {
-	if iscgo && !cgoHasExtraM {
+	if (iscgo || GOOS == "windows") && !cgoHasExtraM {
 		// Can happen if C/C++ code calls Go from a global ctor.
 		// Can not throw, because scheduler is not initialized yet.
 		write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback)))
@@ -4209,8 +4209,13 @@ func checkdead() {
 		return
 	}
 
+	var run0 int32
+	if !iscgo && cgoHasExtraM {
+		run0 = 1
+	}
+
 	run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys
-	if run > 0 {
+	if run > run0 {
 		return
 	}
 	if run < 0 {
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index dfde12a211..fd5ecca03d 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -251,7 +251,34 @@ func TestBlockingCallback(t *testing.T) {
 }
 
 func TestCallbackInAnotherThread(t *testing.T) {
-	// TODO: test a function which calls back in another thread: QueueUserAPC() or CreateThread()
+	d := GetDLL(t, "kernel32.dll")
+	f := func(p uintptr) uintptr {
+		return p
+	}
+	r, _, err := d.Proc("CreateThread").Call(0, 0, syscall.NewCallback(f), 123, 0, 0)
+	if r == 0 {
+		t.Fatalf("CreateThread failed: %v", err)
+	}
+	h := syscall.Handle(r)
+	defer syscall.CloseHandle(h)
+	switch s, err := syscall.WaitForSingleObject(h, 100); s {
+	case syscall.WAIT_OBJECT_0:
+		break
+	case syscall.WAIT_TIMEOUT:
+		t.Fatal("timeout waiting for thread to exit")
+	case syscall.WAIT_FAILED:
+		t.Fatalf("WaitForSingleObject failed: %v", err)
+	default:
+		t.Fatalf("WaitForSingleObject returns unexpected value %v", s)
+	}
+	var ec uint32
+	r, _, err = d.Proc("GetExitCodeThread").Call(uintptr(h), uintptr(unsafe.Pointer(&ec)))
+	if r == 0 {
+		t.Fatalf("GetExitCodeThread failed: %v", err)
+	}
+	if ec != 123 {
+		t.Fatalf("expected 123, but got %d", ec)
+	}
 }
 
 type cbDLLFunc int // int determines number of callback parameters

@alexbrainman
Copy link
Member Author

Despite my earlier statement about needing a few days to look into this I decided to have a look

Did not take you long to come up with a solution. :-)

Running all.bat hangs the whole OS(!)

I have never seen anything like that. If you care, you can create new issue and someone will investigate.

I have traced this problem to the following 2 tests: TestBreakpoint and TestAbort

Normally hanged test are debugged by adding -timeout parameter. -timeout forces test to crash, and crash prints stack trace, and you can see where test hangs. But your test hangs whole OS, so I don't see how my advise is useful here.

I believe that the problem lies with checkdead, which should be improved to handle the extra M in cgo and the patch above.

I do not know, if your program should hang or not. So I created #25538 to confirm.

The following patch passes all tests on Windows

Yes this works for me too. On Windows 10 here.

I am not familiar with scheduler, so I cannot confirm your patch is correct or not. But if you send your change for review https://golang.org/doc/contribute.html someone will check your code.

Thank you.

Alex

@billziss-gh
Copy link
Contributor

billziss-gh commented May 25, 2018

I am not familiar with scheduler, so I cannot confirm your patch is correct or not. But if you send your change for review https://golang.org/doc/contribute.html someone will check your code.

Thanks for the pointer. The document mentions Gerrit, which I am not familiar with, but it looks like I can now submit the patch as a GitHub PR as well. The Google CLA looks fairly benign, so I am inclined to sign it.

Re: the patch itself. A large portion of this patch includes your test @alexbrainman which I would not be able to submit under the Google CLA (I would be violating term 5 or have to follow the process in term 7, which I do not understand). So I can only submit my changes against runtime/proc.go.

@billziss-gh
Copy link
Contributor

I have now submitted PR # 25575, which includes the changes in runtime/proc.go, but not the test in TestCallbackInAnotherThread. (As explained above I cannot submit the test as it is not my work.)

@gopherbot
Copy link

Change https://golang.org/cl/114755 mentions this issue: runtime: implement TestCallbackInAnotherThread

@alexbrainman
Copy link
Member Author

it looks like I can now submit the patch as a GitHub PR as well.

Yes that should work. Unfortunately your PR #25575 seems stuck - you created and signed CLA 4 hours ago, and Gobot should have created Gerrit CL by now. We'll give it little more time, and maybe ping for help. It is not good that it is weekend now, perhaps we'll have to wait for next week.

large portion of this patch includes your test @alexbrainman which I would not be able to submit under the Google CLA

I contributed to Go before, so I have signed CLA, and you could take my code as part of your change. But I created https://go-review.googlesource.com/c/go/+/114755 in case we want two separate changes. I don't care how, as long as your change goes in with the test.

I have now submitted PR # 25575, which includes the changes in runtime/proc.go

Thank you for fixing this. It have very little free time nowdays.

Alex

@billziss-gh
Copy link
Contributor

Unfortunately your PR #25575 seems stuck...

I see. Obviously I am unfamiliar with the process, so I did not know what to expect. Perhaps the "gobot" needs a kick? :)

I contributed to Go before, so I have signed CLA...

You mean to tell me that you do not work for Google, but somehow you have 710+ commits on this project? Respect!

and you could take my code as part of your change. But I created https://go-review.googlesource.com/c/go/+/114755 in case we want two separate changes. I don't care how, as long as your change goes in with the test.

I would prefer it if we kept the changes separate. The CLA states in term 5 that: "You represent that each of Your Contributions is Your original creation...". I find it inadvisable to knowingly violate the CLA on the same day I signed it :)

Thank you for fixing this. It have very little free time nowdays.

You are welcome. I very much understand the no-time argument.

gopherbot pushed a commit that referenced this issue May 26, 2018
Updates #6751

Change-Id: Ibb176a17e67c67f855bc4f3e5462dddaedaa8a58
Reviewed-on: https://go-review.googlesource.com/114755
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
@alexbrainman
Copy link
Member Author

Perhaps the "gobot" needs a kick? :)

Perhaps it does need a kick. I pinged Brad on your PR, maybe he will help. It is getting late Friday in West coast of USA, so it might be a while when someone will help - Go Team members are real people. But we will get your change reviewed.

You mean to tell me that you do not work for Google,

No, I do not work for Google.

Alex

@gopherbot
Copy link

Change https://golang.org/cl/114802 mentions this issue: runtime: handle windows callback on non-go thread

@tohosys
Copy link

tohosys commented Jun 4, 2018

Dear alexbrainman
I got a same problem like this;

I tried your old below sample but same result.

Could you please give me some solution ?
Thank you very much~

Best Regards,
JayKim

@alexbrainman
Copy link
Member Author

I got a same problem like this;

Same problem as #6751 ? As you can see, the issue is still opened, so the problem still remains. But @billziss-gh proposed solution - you can try his solution at https://golang.org/cl/114802.

Alex

@golang golang locked and limited conversation to collaborators Jun 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

10 participants