Skip to content

Commit 956dce4

Browse files
committed
compiler/natives/src/internal/poll: Create no-op I/O poller implementation.
gopherjs test uses tempFile to create temporary files during execution of examples. tempFile calls os.OpenFile to create a file. os.OpenFile calls newFile, which in Go 1.9 tries to add the file to the runtime poller. Normally, on OSes like darwin, linux, etc., this tries to use a real runtime poller from internal/poll package. We override that package so that a no-op implementation (based on NaCL implementation) is used instead. Fixes: Error: runtime error: native function not implemented: internal/poll.runtime_pollServerInit After this change, some basic tests pass: $ gopherjs test errors github.com/gopherjs/gopherjs/tests PASS ok errors 0.453s PASS ok github.com/gopherjs/gopherjs/tests 0.606s
1 parent b946d67 commit 956dce4

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

build/build.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,15 @@ func importWithSrcDir(path string, srcDir string, mode build.ImportMode, install
9393

9494
switch path {
9595
case "os":
96-
pkg.GoFiles = stripExecutable(pkg.GoFiles) // Need to strip executable implementation files, because some of them contain package scope variables that perform (indirectly) syscalls on init.
96+
pkg.GoFiles = excludeExecutable(pkg.GoFiles) // Need to exclude executable implementation files, because some of them contain package scope variables that perform (indirectly) syscalls on init.
9797
case "runtime":
9898
pkg.GoFiles = []string{"error.go"}
9999
case "runtime/internal/sys":
100100
pkg.GoFiles = []string{fmt.Sprintf("zgoos_%s.go", buildContext.GOOS), "zversion.go"}
101101
case "runtime/pprof":
102102
pkg.GoFiles = nil
103+
case "internal/poll":
104+
pkg.GoFiles = exclude(pkg.GoFiles, "fd_poll_runtime.go")
103105
case "crypto/rand":
104106
pkg.GoFiles = []string{"rand.go", "util.go"}
105107
case "crypto/x509":
@@ -131,9 +133,9 @@ func importWithSrcDir(path string, srcDir string, mode build.ImportMode, install
131133
return &PackageData{Package: pkg, JSFiles: jsFiles}, nil
132134
}
133135

134-
// stripExecutable strips all executable implementation .go files.
136+
// excludeExecutable excludes all executable implementation .go files.
135137
// They have "executable_" prefix.
136-
func stripExecutable(goFiles []string) []string {
138+
func excludeExecutable(goFiles []string) []string {
137139
var s []string
138140
for _, f := range goFiles {
139141
if strings.HasPrefix(f, "executable_") {
@@ -144,6 +146,21 @@ func stripExecutable(goFiles []string) []string {
144146
return s
145147
}
146148

149+
// exclude returns files, excluding specified files.
150+
func exclude(files []string, exclude ...string) []string {
151+
var s []string
152+
Outer:
153+
for _, f := range files {
154+
for _, e := range exclude {
155+
if f == e {
156+
continue Outer
157+
}
158+
}
159+
s = append(s, f)
160+
}
161+
return s
162+
}
163+
147164
// ImportDir is like Import but processes the Go package found in the named
148165
// directory.
149166
func ImportDir(dir string, mode build.ImportMode, installSuffix string, buildTags []string) (*PackageData, error) {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// +build js
2+
3+
package poll
4+
5+
import "time"
6+
7+
// pollDesc is a no-op implementation of an I/O poller for GOARCH=js.
8+
type pollDesc struct {
9+
closing bool
10+
}
11+
12+
func (pd *pollDesc) init(fd *FD) error { return nil }
13+
14+
func (pd *pollDesc) close() {}
15+
16+
func (pd *pollDesc) evict() { pd.closing = true }
17+
18+
func (pd *pollDesc) prepare(mode int, isFile bool) error {
19+
if pd.closing {
20+
return errClosing(isFile)
21+
}
22+
return nil
23+
}
24+
25+
func (pd *pollDesc) prepareRead(isFile bool) error { return pd.prepare('r', isFile) }
26+
27+
func (pd *pollDesc) prepareWrite(isFile bool) error { return pd.prepare('w', isFile) }
28+
29+
func (pd *pollDesc) wait(mode int, isFile bool) error {
30+
if pd.closing {
31+
return errClosing(isFile)
32+
}
33+
return ErrTimeout
34+
}
35+
36+
func (pd *pollDesc) waitRead(isFile bool) error { return pd.wait('r', isFile) }
37+
38+
func (pd *pollDesc) waitWrite(isFile bool) error { return pd.wait('w', isFile) }
39+
40+
func (*pollDesc) waitCanceled(mode int) {}
41+
42+
func (*FD) SetDeadline(t time.Time) error { return nil }
43+
44+
func (*FD) SetReadDeadline(t time.Time) error { return nil }
45+
46+
func (*FD) SetWriteDeadline(t time.Time) error { return nil }
47+
48+
// PollDescriptor returns the descriptor being used by the poller,
49+
// or ^uintptr(0) if there isn't one. This is only used for testing.
50+
func PollDescriptor() uintptr {
51+
return ^uintptr(0)
52+
}

0 commit comments

Comments
 (0)