// FuncOf returns a function to be used by JavaScript. // // The Go function fn is called with the value of JavaScript's "this" keyword and the // arguments of the invocation. The return value of the invocation is // the result of the Go function mapped back to JavaScript according to ValueOf. // // Invoking the wrapped Go function from JavaScript will // pause the event loop and spawn a new goroutine. // Other wrapped functions which are triggered during a call from Go to JavaScript // get executed on the same goroutine. // // As a consequence, if one wrapped function blocks, JavaScript's event loop // is blocked until that function returns. Hence, calling any async JavaScript // API, which requires the event loop, like fetch (http.Client), will cause an // immediate deadlock. Therefore a blocking function should explicitly start a // new goroutine. // // Func.Release must be called to free up resources when the function will not be invoked any more. public static Func FuncOf(Action <Value, slice <Value> > fn) { funcsMu.Lock(); var id = nextFuncID; nextFuncID++; funcs[id] = fn; funcsMu.Unlock(); return(new Func(id: id, Value: jsGo.Call("_makeFuncWrapper", id), )); }
private static long nextPort() => func((defer, _, __) => { portCounterMu.Lock(); defer(portCounterMu.Unlock()); portCounter++; return(portCounter); });
// hashType returns a hash for t such that // types.Identical(x, y) => hashType(x) == hashType(y). private static long hashType(types.Type t) { mu.Lock(); var h = int(hasher.Hash(t)); mu.Unlock(); return(h); }
private static @string nextRandom() { randmu.Lock(); var r = rand; if (r == 0L) { r = reseed(); } r = r * 1664525L + 1013904223L; // constants from Numerical Recipes rand = r; randmu.Unlock(); return strconv.Itoa(int(1e9F + r % 1e9F))[1L..];
public static void Fixwd() => func((defer, _, __) => { wdmu.Lock(); defer(wdmu.Unlock()); fixwdLocked(); });