Skip to content

Commit

Permalink
Allow JobQueue to concurrently run jobs (#3036)
Browse files Browse the repository at this point in the history
* Allow `JobQueue` to concurrently run jobs

* Remove bounds on `run_jobs_async`
  • Loading branch information
jedel1043 authored Jun 13, 2023
1 parent 5da8846 commit 0e1b32a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
15 changes: 14 additions & 1 deletion boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,19 @@ impl<'host> Context<'host> {
self.clear_kept_objects();
}

/// Asynchronously runs all the jobs in the job queue.
///
/// # Note
///
/// Concurrent job execution cannot be guaranteed by the engine, since this depends on the
/// specific handling of each [`JobQueue`]. If you need to ensure that jobs are executed
/// concurrently, you can provide a custom implementor of `JobQueue` to the context.
#[allow(clippy::future_not_send)]
pub async fn run_jobs_async(&mut self) {
self.job_queue().run_jobs_async(self).await;
self.clear_kept_objects();
}

/// Abstract operation [`ClearKeptObjects`][clear].
///
/// Clears all objects maintained alive by calls to the [`AddToKeptObjects`][add] abstract
Expand All @@ -424,7 +437,7 @@ impl<'host> Context<'host> {

/// Retrieves the current stack trace of the context.
#[inline]
pub fn stack_trace(&mut self) -> impl Iterator<Item = &CallFrame> {
pub fn stack_trace(&self) -> impl Iterator<Item = &CallFrame> {
self.vm.frames.iter().rev()
}

Expand Down
20 changes: 20 additions & 0 deletions boa_engine/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,26 @@ pub trait JobQueue {
/// to do this will leave the inner `Promise` in the `pending` state, which won't call any `then`
/// or `catch` handlers, even if `future` was already completed.
fn enqueue_future_job(&self, future: FutureJob, context: &mut Context<'_>);

/// Asynchronously runs all jobs in the queue.
///
/// Running a job could enqueue more jobs in the queue. The implementor of the trait
/// determines if the method should loop until there are no more queued jobs or if
/// it should only run one iteration of the queue.
///
/// By default forwards to [`JobQueue::run_jobs`]. Implementors using async should override this
/// with a proper algorithm to run jobs asynchronously.
fn run_jobs_async<'a, 'ctx, 'host, 'fut>(
&'a self,
context: &'ctx mut Context<'host>,
) -> Pin<Box<dyn Future<Output = ()> + 'fut>>
where
'a: 'fut,
'ctx: 'fut,
'host: 'fut,
{
Box::pin(async { self.run_jobs(context) })
}
}

/// A job queue that does nothing.
Expand Down

0 comments on commit 0e1b32a

Please sign in to comment.