Commit c07f2b00 authored by Richard Musiol's avatar Richard Musiol Committed by Brad Fitzpatrick

syscall/js: rename Callback.Close to Release and expose Callback.Value

This makes Callback more in line with TypedArray. The name "Release" is
better than "Close" because the function does not implement io.Closer.

Change-Id: I23829a14b1c969ceb04608afd9505fd5b4b0df2e
Reviewed-on: https://go-review.googlesource.com/121216
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 257d6c48
...@@ -110,7 +110,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { ...@@ -110,7 +110,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) {
case <-req.Context().Done(): case <-req.Context().Done():
} }
}) })
defer success.Close() defer success.Release()
failure := js.NewCallback(func(args []js.Value) { failure := js.NewCallback(func(args []js.Value) {
err := fmt.Errorf("net/http: fetch() failed: %s", args[0].String()) err := fmt.Errorf("net/http: fetch() failed: %s", args[0].String())
select { select {
...@@ -118,7 +118,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { ...@@ -118,7 +118,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) {
case <-req.Context().Done(): case <-req.Context().Done():
} }
}) })
defer failure.Close() defer failure.Release()
respPromise.Call("then", success, failure) respPromise.Call("then", success, failure)
select { select {
case <-req.Context().Done(): case <-req.Context().Done():
...@@ -171,7 +171,7 @@ func (r *streamReader) Read(p []byte) (n int, err error) { ...@@ -171,7 +171,7 @@ func (r *streamReader) Read(p []byte) (n int, err error) {
a.Release() a.Release()
bCh <- value bCh <- value
}) })
defer success.Close() defer success.Release()
failure := js.NewCallback(func(args []js.Value) { failure := js.NewCallback(func(args []js.Value) {
// Assumes it's a TypeError. See // Assumes it's a TypeError. See
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
...@@ -180,7 +180,7 @@ func (r *streamReader) Read(p []byte) (n int, err error) { ...@@ -180,7 +180,7 @@ func (r *streamReader) Read(p []byte) (n int, err error) {
// the read method. // the read method.
errCh <- errors.New(args[0].Get("message").String()) errCh <- errors.New(args[0].Get("message").String())
}) })
defer failure.Close() defer failure.Release()
r.stream.Call("read").Call("then", success, failure) r.stream.Call("read").Call("then", success, failure)
select { select {
case b := <-bCh: case b := <-bCh:
...@@ -234,7 +234,7 @@ func (r *arrayReader) Read(p []byte) (n int, err error) { ...@@ -234,7 +234,7 @@ func (r *arrayReader) Read(p []byte) (n int, err error) {
a.Release() a.Release()
bCh <- value bCh <- value
}) })
defer success.Close() defer success.Release()
failure := js.NewCallback(func(args []js.Value) { failure := js.NewCallback(func(args []js.Value) {
// Assumes it's a TypeError. See // Assumes it's a TypeError. See
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
...@@ -242,7 +242,7 @@ func (r *arrayReader) Read(p []byte) (n int, err error) { ...@@ -242,7 +242,7 @@ func (r *arrayReader) Read(p []byte) (n int, err error) {
// See https://fetch.spec.whatwg.org/#concept-body-consume-body for reasons this might error. // See https://fetch.spec.whatwg.org/#concept-body-consume-body for reasons this might error.
errCh <- errors.New(args[0].Get("message").String()) errCh <- errors.New(args[0].Get("message").String())
}) })
defer failure.Close() defer failure.Release()
r.arrayPromise.Call("then", success, failure) r.arrayPromise.Call("then", success, failure)
select { select {
case b := <-bCh: case b := <-bCh:
......
...@@ -46,8 +46,8 @@ var ( ...@@ -46,8 +46,8 @@ var (
// A Callback can be passed to functions of this package that accept interface{}, // A Callback can be passed to functions of this package that accept interface{},
// for example Value.Set and Value.Call. // for example Value.Set and Value.Call.
type Callback struct { type Callback struct {
Value // the JavaScript function that queues the callback for execution
id uint32 id uint32
enqueueFn Value // the JavaScript function that queues the callback for execution
} }
// NewCallback returns a wrapped callback function. It can be passed to functions of this package // NewCallback returns a wrapped callback function. It can be passed to functions of this package
...@@ -59,7 +59,7 @@ type Callback struct { ...@@ -59,7 +59,7 @@ type Callback struct {
// As a consequence, if one callback blocks this goroutine, other callbacks will not be processed. // As a consequence, if one callback blocks this goroutine, other callbacks will not be processed.
// A blocking callback should therefore explicitly start a new goroutine. // A blocking callback should therefore explicitly start a new goroutine.
// //
// Callback.Close must be called to free up resources when the callback will not be used any more. // Callback.Release must be called to free up resources when the callback will not be used any more.
func NewCallback(fn func(args []Value)) Callback { func NewCallback(fn func(args []Value)) Callback {
callbackLoopOnce.Do(func() { callbackLoopOnce.Do(func() {
go callbackLoop() go callbackLoop()
...@@ -71,8 +71,8 @@ func NewCallback(fn func(args []Value)) Callback { ...@@ -71,8 +71,8 @@ func NewCallback(fn func(args []Value)) Callback {
callbacks[id] = fn callbacks[id] = fn
callbacksMu.Unlock() callbacksMu.Unlock()
return Callback{ return Callback{
Value: makeCallbackHelper.Invoke(id, pendingCallbacks, resolveCallbackPromise),
id: id, id: id,
enqueueFn: makeCallbackHelper.Invoke(id, pendingCallbacks, resolveCallbackPromise),
} }
} }
...@@ -95,17 +95,19 @@ func NewEventCallback(flags EventCallbackFlag, fn func(event Value)) Callback { ...@@ -95,17 +95,19 @@ func NewEventCallback(flags EventCallbackFlag, fn func(event Value)) Callback {
fn(args[0]) fn(args[0])
}) })
return Callback{ return Callback{
id: c.id, Value: makeEventCallbackHelper.Invoke(
enqueueFn: makeEventCallbackHelper.Invoke(
flags&PreventDefault != 0, flags&PreventDefault != 0,
flags&StopPropagation != 0, flags&StopPropagation != 0,
flags&StopImmediatePropagation != 0, flags&StopImmediatePropagation != 0,
c, c,
), ),
id: c.id,
} }
} }
func (c Callback) Close() { // Release frees up resources allocated for the callback.
// The callback must not be invoked after calling Release.
func (c Callback) Release() {
callbacksMu.Lock() callbacksMu.Lock()
delete(callbacks, c.id) delete(callbacks, c.id)
callbacksMu.Unlock() callbacksMu.Unlock()
......
...@@ -99,7 +99,7 @@ func ValueOf(x interface{}) Value { ...@@ -99,7 +99,7 @@ func ValueOf(x interface{}) Value {
case TypedArray: case TypedArray:
return x.Value return x.Value
case Callback: case Callback:
return x.enqueueFn return x.Value
case nil: case nil:
return valueNull return valueNull
case bool: case bool:
......
...@@ -214,7 +214,7 @@ func TestCallback(t *testing.T) { ...@@ -214,7 +214,7 @@ func TestCallback(t *testing.T) {
} }
c <- struct{}{} c <- struct{}{}
}) })
defer cb.Close() defer cb.Release()
js.Global().Call("setTimeout", cb, 0, 42) js.Global().Call("setTimeout", cb, 0, 42)
<-c <-c
} }
...@@ -234,10 +234,10 @@ func TestEventCallback(t *testing.T) { ...@@ -234,10 +234,10 @@ func TestEventCallback(t *testing.T) {
cb := js.NewEventCallback(flags, func(event js.Value) { cb := js.NewEventCallback(flags, func(event js.Value) {
c <- struct{}{} c <- struct{}{}
}) })
defer cb.Close() defer cb.Release()
event := js.Global().Call("eval", fmt.Sprintf("({ called: false, %s: function() { this.called = true; } })", name)) event := js.Global().Call("eval", fmt.Sprintf("({ called: false, %s: function() { this.called = true; } })", name))
js.ValueOf(cb).Invoke(event) cb.Invoke(event)
if !event.Get("called").Bool() { if !event.Get("called").Bool() {
t.Errorf("%s not called", name) t.Errorf("%s not called", name)
} }
...@@ -250,7 +250,7 @@ func ExampleNewCallback() { ...@@ -250,7 +250,7 @@ func ExampleNewCallback() {
var cb js.Callback var cb js.Callback
cb = js.NewCallback(func(args []js.Value) { cb = js.NewCallback(func(args []js.Value) {
fmt.Println("button clicked") fmt.Println("button clicked")
cb.Close() // close the callback if the button will not be clicked again cb.Release() // release the callback if the button will not be clicked again
}) })
js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb) js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment