> There's nothing preventing you from running C++ code in the background on 
the non-main JS thread to get events, and then use uv_async_send to send 
those events, or otherwise trigger JS to run.... is it really JS level code 
that has to be compute bound? Can't you like maybe interject a check the 
clock and every 250 milliseconds return to allow promises to resolve and 
other JS scheduled events? .   


Sure, but how? Given the js code is written by users and out of my control. 
I can deliver events from a different thread or via uv loop is doesn't 
matter, the issue I have is that I have to interrupt the isolate that is 
running to do it, and we're saying there is no way to do that and leave the 
isolate in a safe state.

The project you linked just uses v8 apis, so if there is no API in v8 to do 
it, I'm not sure how the ptoject does that, or I'm misunderstanding the 
docs.
On Tuesday, 22 April 2025 at 07:37:27 UTC+1 d3c...@gmail.com wrote:

> On Mon, Apr 21, 2025 at 11:24 PM jmr <audrius.b...@gmail.com> wrote:
>
>> What does idle state mean?
>>
>> The code my users run never terminates, i.e., it permanently spins 
>> waiting for events, so the stack depth never goes to 0.
>> None of the code is async, as the version of spidermonkey used did not 
>> have it.
>> They potentially call some native functions (sleep which literally does 
>> thread::sleep in C++) etc, but otherwise the code is non-async and never 
>> terminating, and always at non-zero stack depth.
>>
>> This sounds like the isolate is never idle, hence there is no nice way to 
>> do this?
>>
>
> the isolate-vm project has a execution timeout it can do - I'm not sure if 
> that's only able to kill stuff - or if it's able to interrupt and interject 
> code to run.
>  
>
>>
>> Surely chome somehow delivers events/setTimeout timers even if the users 
>> code has a while(true) {} ?
>> I assume node does it too somehow?
>>
>
> False.
>
> In the console you can enter `setInterval( ()=>{console.log("tick");, 500 
> )`  and click the run button... should start generated console message.
> You can then enter 'while( true);' and I got one more 'tick' but no 
> further ticks, and can not enter any further commands.
>
>  
>
>>
>> I guess I could check for events to deliver in every native function I 
>> expose, but that feels a bit yuck.
>>
>
> I formulate everything as events and never poll, so this is a bit foreign 
> to me.  Yes you will have to every once in a while poke the C++ code to do 
> something if you're going to occupy the stack.
>  
>
>> I could also continue doing it in the interrupt, the docs say don't do 
>> it, but it seems to work and nothing panics (I have not run very 
>> complicated code however, not sure at what point it breaks)
>>
>
> I had a feature in my code which would allow blocking a thread's 
> execution, and call out to trigger the idle function (in node it's like  
> ProcessTickCallback() or something)... and was able to cause JS code to run 
> on a deeper stack, but it was kind of brittle as I went on to build more 
> with it, then I found I had to unwind further back to finish earlier 
> functions; and just wasn't practical how I was doing it.  
>
> There's nothing preventing you from running C++ code in the background on 
> the non-main JS thread to get events, and then use uv_async_send to send 
> those events, or otherwise trigger JS to run.... is it really JS level code 
> that has to be compute bound?  Can't you like maybe interject a check the 
> clock and every 250 milliseconds return to allow promises to resolve and 
> other JS scheduled events?  .   
>
>
>> Thanks.
>> On Tuesday, 22 April 2025 at 02:26:21 UTC+1 d3c...@gmail.com wrote:
>>
>>> On Mon, Apr 21, 2025 at 6:21 PM J Decker <d3c...@gmail.com> wrote:
>>>
>>>> You will have to wait for the JS stack to be idle for events to get 
>>>> dispatched... even promises are only dispatched from an idle state in the 
>>>> JS stack (where it has returned fully).
>>>>
>>>> You can call any JS functions in the initialization callback - but you 
>>>> cannot use the isolate or make a handle scope in not the right thread... 
>>>> so 
>>>> you have to wait for the uv_async_init'ed callback to be triggered before 
>>>> doing queued work.
>>>>
>>>> If this isn't sufficient and you really need parallel or injected 
>>>> execution - for node there's a worker-thread module ; but the eventual 
>>>> results have to be dispatched at the idle level still...
>>>> https://github.com/laverdet/isolated-vm for example... (this is also a 
>>>> C++ thread that deals directly with allocating and managing isolates)
>>>>
>>>> you use `uv_async_init` once, which initialized a uv_async_t handle to 
>>>> be associated with a loop.  You then use uv_async_send( handle ); which 
>>>> triggers dispatching to that routine; you will have to create a handle 
>>>> scope in that callback before doing JS functions.  The handle can only be 
>>>> closed in the main thread also.   The work can be queued to internal 
>>>> tracking, and when the async callback runs, it just checks for outstanding 
>>>> work, and calls appropriate JS callbacks.
>>>>
>>>
>>> By default - initializing handles for for uv_async_send to work - they 
>>> add a reference that keeps (node) running (I see this isn't actually a node 
>>> specific thread though)... you can async_unref( handle ) and that will keep 
>>> it schedulable, but not hold the process open.  (may times like opening a 
>>> server socket, you'd want the process to not exit until that socket is 
>>> closed (which is probably never) but other situations might not be critical 
>>> enough to hold the process - my GUI interface has gone this way and the 
>>> window event dispatch don't actually keep the process open; but then I 
>>> ended up with a keep-alive setTimeout()... Just thought it might be useful 
>>> to note.
>>>  
>>>
>>>>
>>>> On Mon, Apr 21, 2025 at 9:51 AM jmr <audrius.b...@gmail.com> wrote:
>>>>
>>>>> Ok, seems that I CAN call js functions from within RequestInterrupt, 
>>>>> things seem to work.
>>>>>
>>>>> I guess I'm confused what this means in that case: "Registered 
>>>>> |callback| must not reenter interrupted Isolate."
>>>>>
>>>>>
>>>>>
>>>>> On Monday, 21 April 2025 at 17:41:21 UTC+1 jmr wrote:
>>>>>
>>>>>> I'm porting an application that is using SpiderMonkey for embedding, 
>>>>>> and I have a few questions.
>>>>>>
>>>>>> One of the things my application does is, it allows user (in 
>>>>>> javascript) to register for events:
>>>>>>
>>>>>> func handler(...) { {}
>>>>>> registerEventHandler("evetName", handler);
>>>>>>
>>>>>> In C++, I then store these handlers to be called later once the event 
>>>>>> arrives.
>>>>>>
>>>>>> Once the event arrives (different thread than isolate is running on), 
>>>>>> I store it in a pending event list for the runtime (isolate), I then 
>>>>>> call JS_RequestInterruptCallback which interrupts the execution of the 
>>>>>> runtime (isolate), and drops into my C++ interrupt callback.
>>>>>>
>>>>>> From my C++ callback, I check for pending events, and call the user 
>>>>>> provided functions (re-entering the isolate) delivering the events, and 
>>>>>> resume execution to the user.
>>>>>>
>>>>>> Seems that with v8, I can get quite close to this, except 
>>>>>> isolate->RequestInterrupt does not allow re-entering the isolate/calling 
>>>>>> user code, making this not work.
>>>>>>
>>>>>> I tried using EnqueueMicrotask but seems those are never delivered 
>>>>>> automatically unless the script stops, or I call 
>>>>>> PerformMicrotaskCheckpoint 
>>>>>> (which then ends up on the wrong, calling thread)
>>>>>>
>>>>>> I tried posting a task to the platform 
>>>>>> (platform->GetForegroundTaskRunner(isolate)->PostTask), but given the 
>>>>>> script is long lived, I don't think this ever gets delivered.
>>>>>>
>>>>>> I tried using Locker(isolate) + Isolate::Scope(isolate) 
>>>>>> + isolate->GetCurrentContext() from the event thread, and then calling 
>>>>>> the 
>>>>>> callbacks, but this crashes non-deterministically, sometimes with 
>>>>>> "Invoke 
>>>>>> in DisallowJavascriptExecutionScope".
>>>>>>
>>>>>> Any guidance is appreciated.
>>>>>> Thanks.
>>>>>>
>>>>>> -- 
>>>>> -- 
>>>>> v8-users mailing list
>>>>> v8-u...@googlegroups.com
>>>>> http://groups.google.com/group/v8-users
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "v8-users" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to v8-users+u...@googlegroups.com.
>>>>> To view this discussion visit 
>>>>> https://groups.google.com/d/msgid/v8-users/12e0876e-96b5-451f-8c88-11b4c4d8efd3n%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/v8-users/12e0876e-96b5-451f-8c88-11b4c4d8efd3n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> -- 
>> -- 
>> v8-users mailing list
>> v8-u...@googlegroups.com
>> http://groups.google.com/group/v8-users
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "v8-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to v8-users+u...@googlegroups.com.
>>
> To view this discussion visit 
>> https://groups.google.com/d/msgid/v8-users/1a454904-e079-48fd-849b-cb3f086a2c1cn%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/v8-users/1a454904-e079-48fd-849b-cb3f086a2c1cn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/v8-users/5fae024b-c420-479d-8f43-acedb515b010n%40googlegroups.com.

Reply via email to