Skip to content

Commit

Permalink
Allow JobQueue to concurrently run jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Jun 12, 2023
1 parent 827c055 commit a9cf04d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
18 changes: 17 additions & 1 deletion boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,22 @@ 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<'a>(self: &'a mut Context<'host>)
where
'host: 'a,
{
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 +440,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 a9cf04d

Please sign in to comment.