On Fri, May 11, 2018 at 7:36 PM, <jer...@fly.io> wrote:
> I've been wondering if it's possible to concurrently use v8::Locker.
>
> I'm binding to v8 from a single-threaded language that uses fibers for
> concurrency (Crystal.) Since it's a single thread, v8::Locker is always
> instantly available.
>
> This seems fine, the bigger issue if with Context::Scope.
>
> I'm concurrently entering and exiting the same context from multiple fibers
> and I keep stumbling upon:
>
> #
> # Fatal error in v8::Context::Exit()
> # Cannot exit non-entered context
> #
>
> Which came to make sense to me. I'm passing around a pointer to a
> Persistent<Context>. In the function I concurrently access, I'm getting the
> Local from it (with the isolate) and creating a Context::Scope. The same
> Local<Context> might be exited more than once. I expect Enter is a noop if
> the Context has already been entered.
It isn't. Enter() and Exit() calls need to match up.
> My fix was to use a fiber-safe mutex to only allow one isolate locking and
> context scoping at any given time.
>
> Is this normal? Any way around it?
You may want to take a look at node-fibers. It uses a thread-local
storage hack to trick V8 into supporting fibers.
https://github.com/laverdet/node-fibers/blob/4786aef736ab8285d29e9476e3615abbd3935d37/src/coroutine.cc#L76-L123
On May 11, 2018 at 4:36:12 PM, Ben Noordhuis (in...@bnoordhuis.nl) wrote:
On Fri, May 11, 2018 at 10:05 PM, <jer...@fly.io> wrote:
> Yea, that makes sense. They do match up, but the function I use to get the
> context handle may be called more than once at the same time. I mean, the
> same context may be entered multiple times concurrently and exited at
> different times. As soon as it's exited once by one of the concurrent tasks,
> it will throw that error I pasted if it's exited again.
>
> void __crystal_ctx_scoped(char *id);
>
> void v8_with_ctx_scope(Isolate* iso, Context* ctxptr, char* id) {
> v8::HandleScope handle_scope(iso);
> v8::Local<v8::Context> ctx = ctxptr->Get(iso);
> {
> v8::Context::Scope context_scope(ctx);
> __crystal_ctx_scoped(id);
> }
> }
>
> The __crystal_ctx_scoped is a callback exposed from Crystal to C. It
> dispatches to the right context via the provided id.
You mean __crystal_ctx_scoped() directly or indirectly calls
v8_with_ctx_scope() again? Yes, that's going to be problematic.
Another fiber might call v8_with_ctx_scope() again before the first call to it is done. With the same context. When I added a mutex, the problem seemed fixed. I just want to make sure this is limitation: you can't enter the same context more than one at the same time, or else exiting will exit from both "enters".
At what point or points do you call into V8? You could maintain a
stack of contexts and call Enter() and Exit() manually but that only
works when there are no V8 stack frames (either JS or C++) on the call
stack.
Hmm. It's called into when there's an HTTP request coming in or when there's a callback fired (like a setTimeout.)
Not entirely sure what kind of information you're looking for :) There's probably going to be frames on the call stack.
--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to a topic in the Google Groups "v8-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/v8-users/5EbYZlO5VTY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to v8-users+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.