Propagates error return Close to public API (#375)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-03-15 20:12:16 +08:00
committed by GitHub
parent 91444c7af9
commit f85857d081
5 changed files with 24 additions and 20 deletions

View File

@@ -57,8 +57,9 @@ func (m *ModuleContext) WithContext(ctx context.Context) publicwasm.Module {
return m
}
func (m *ModuleContext) Close() {
m.store.CloseModule(m.module.Name)
// Close implements io.Closer
func (m *ModuleContext) Close() error {
return m.store.CloseModule(m.module.Name)
}
// Memory implements wasm.Module Memory

View File

@@ -338,12 +338,13 @@ func (s *Store) Instantiate(ctx context.Context, module *Module, name string) (*
}
// CloseModule deallocates resources if a module with the given name exists.
func (s *Store) CloseModule(moduleName string) {
func (s *Store) CloseModule(moduleName string) (err error) {
m := s.module(moduleName)
if m != nil {
m.Engine.Close()
err = m.Engine.Close()
s.deleteModule(moduleName)
}
return
}
// deleteModule makes the moduleName available for instantiation again.

View File

@@ -147,15 +147,15 @@ func TestStore_CloseModule(t *testing.T) {
_, ok = s.modules[importingModuleName]
require.True(t, ok)
// Release the importing module
s.CloseModule(importingModuleName)
// Close the importing module
require.NoError(t, s.CloseModule(importingModuleName))
require.NotContains(t, s.modules, importingModuleName)
// Can re-release the importing module
s.CloseModule(importingModuleName)
// Can re-close the importing module
require.NoError(t, s.CloseModule(importingModuleName))
// Now we release the imported module.
s.CloseModule(importedModuleName)
// Now we close the imported module.
require.NoError(t, s.CloseModule(importedModuleName))
require.Nil(t, s.modules[importedModuleName])
require.NotContains(t, s.modules, importedModuleName)
})
@@ -206,13 +206,13 @@ func TestStore_concurrent(t *testing.T) {
for i := 0; i < goroutines; i++ {
go func(i int) {
defer wg.Done()
s.CloseModule(strconv.Itoa(i))
require.NoError(t, s.CloseModule(strconv.Itoa(i)))
require.NoError(t, err)
}(i)
}
wg.Wait()
s.CloseModule(hm.Name)
require.NoError(t, s.CloseModule(hm.Name))
// All instances are freed.
require.Len(t, s.modules, 0)

View File

@@ -236,9 +236,9 @@ func testHostFunctions(t *testing.T, newRuntimeConfig func() *wazero.RuntimeConf
func testAdhocCloseWhileExecution(t *testing.T, newRuntimeConfig func() *wazero.RuntimeConfig) {
t.Run("singleton", func(t *testing.T) {
r := wazero.NewRuntimeWithConfig(newRuntimeConfig())
var moduleCloser func()
var moduleCloser func() error
_, err := r.NewModuleBuilder("host").ExportFunctions(map[string]interface{}{
"close_module": func() { moduleCloser() }, // Closing while executing itself.
"close_module": func() { _ = moduleCloser() }, // Closing while executing itself.
}).Instantiate()
require.NoError(t, err)
@@ -275,7 +275,7 @@ func testAdhocCloseWhileExecution(t *testing.T, newRuntimeConfig func() *wazero.
require.NoError(t, err)
// Closing the imported module before making call should also safe.
importedModule.Close()
require.NoError(t, importedModule.Close())
// Even we can re-enstantiate the module for the same name.
importedModuleNew, err := r.NewModuleBuilder("host").ExportFunctions(map[string]interface{}{
@@ -284,7 +284,7 @@ func testAdhocCloseWhileExecution(t *testing.T, newRuntimeConfig func() *wazero.
},
}).Instantiate()
require.NoError(t, err)
defer importedModuleNew.Close()
defer importedModuleNew.Close() // nolint
_, err = m.ExportedFunction("close_parent_before_execution").Call(nil)
require.NoError(t, err)

View File

@@ -4,6 +4,7 @@ package wasm
import (
"context"
"fmt"
"io"
"math"
)
@@ -62,6 +63,11 @@ func ValueTypeName(t ValueType) string {
type Module interface {
fmt.Stringer
// Closer (Close) releases resources allocated for this Module. Using this while having outstanding function calls
// is safe. After calling this function, re-instantiating a module for the same name is allowed.
io.Closer
// ^^ io.Closer not due to I/O, but to allow future static analysis to catch leaks (unclosed Closers).
// Context returns any propagated context from the Runtime or a prior function call.
//
// The returned context is always non-nil; it defaults to context.Background.
@@ -87,10 +93,6 @@ type Module interface {
// ExportedGlobal a global exported from this module or nil if it wasn't.
ExportedGlobal(name string) Global
// Close releases resources allocated for this Module. Using this while having outstanding function calls is
// safe. After calling this function, re-instantiating a module for the same name is allowed.
Close()
}
// Function is a WebAssembly 1.0 (20191205) function exported from an instantiated module (wazero.Runtime InstantiateModule).