Skip to content

Commit 1f5753d

Browse files
committed
Remove RMain::initializing flag
And use `RMain::is_r_initialized()` instead
1 parent fafbd8c commit 1f5753d

File tree

1 file changed

+48
-47
lines changed

1 file changed

+48
-47
lines changed

crates/ark/src/interface.rs

+48-47
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ static R_INIT: once_cell::sync::OnceCell<()> = once_cell::sync::OnceCell::new();
156156
static mut R_MAIN: Option<RMain> = None;
157157

158158
pub struct RMain {
159-
initializing: bool,
160159
kernel_init_tx: Bus<KernelInfo>,
161160

162161
/// Whether we are running in Console, Notebook, or Background mode.
@@ -406,17 +405,15 @@ impl RMain {
406405

407406
// Set up the global error handler (after support function initialization)
408407
errors::initialize();
409-
}
410408

411-
// Now that R has started (emitting any startup messages), and now that we have set
412-
// up all hooks and handlers, officially finish the R initialization process to
413-
// unblock the kernel-info request and also allow the LSP to start.
414-
RMain::with_mut(|main| {
415-
log::info!(
416-
"R has started and ark handlers have been registered, completing initialization."
417-
);
418-
main.complete_initialization();
419-
});
409+
// Now that R has started (emitting any startup messages), and now that we have set
410+
// up all hooks and handlers, officially finish the R initialization process to
411+
// unblock the kernel-info request and also allow the LSP to start.
412+
RMain::with_mut(|main| {
413+
log::info!("R has started and ark handlers have been registered, completing initialization.");
414+
main.complete_initialization();
415+
});
416+
}
420417

421418
// Now that R has started and libr and ark have fully initialized, run site and user
422419
// level R profiles, in that order
@@ -431,6 +428,34 @@ impl RMain {
431428
crate::sys::interface::run_r();
432429
}
433430

431+
/// Completes the kernel's initialization.
432+
/// Unlike `RMain::start()`, this has access to `R_MAIN`'s state, such as
433+
/// the kernel-info banner.
434+
/// SAFETY: Can only be called from the R thread, and only once.
435+
pub unsafe fn complete_initialization(&mut self) {
436+
let version = unsafe {
437+
let version = Rf_findVarInFrame(R_BaseNamespace, r_symbol!("R.version.string"));
438+
RObject::new(version).to::<String>().unwrap()
439+
};
440+
441+
// Initial input and continuation prompts
442+
let input_prompt: String = harp::get_option("prompt").try_into().unwrap();
443+
let continuation_prompt: String = harp::get_option("continue").try_into().unwrap();
444+
445+
let kernel_info = KernelInfo {
446+
version: version.clone(),
447+
banner: self.banner_output.clone(),
448+
input_prompt: Some(input_prompt),
449+
continuation_prompt: Some(continuation_prompt),
450+
};
451+
452+
log::info!("Sending kernel info: {version}");
453+
self.kernel_init_tx.broadcast(kernel_info);
454+
455+
// Thread-safe initialisation flag for R
456+
R_INIT.set(()).expect("`R_INIT` can only be set once");
457+
}
458+
434459
pub fn new(
435460
kernel: Arc<Mutex<Kernel>>,
436461
tasks_interrupt_rx: Receiver<RTask>,
@@ -445,7 +470,6 @@ impl RMain {
445470
session_mode: SessionMode,
446471
) -> Self {
447472
Self {
448-
initializing: true,
449473
r_request_rx,
450474
comm_manager_tx,
451475
stdin_request_tx,
@@ -474,14 +498,23 @@ impl RMain {
474498

475499
/// Wait for complete R initialization
476500
///
477-
/// Wait for R being ready to take input (i.e. `ReadConsole` was called).
478-
/// Resolves as the same time as the `Bus<KernelInfo>` init channel does.
501+
/// Wait for R being ready to evaluate R code. Resolves as the same time as
502+
/// the `Bus<KernelInfo>` init channel does.
479503
///
480504
/// Thread-safe.
481505
pub fn wait_r_initialized() {
482506
R_INIT.wait();
483507
}
484508

509+
/// Has R completed initialization
510+
///
511+
/// I.e. is it ready to evaluate R code.
512+
///
513+
/// Thread-safe.
514+
pub fn is_r_initialized() -> bool {
515+
R_INIT.get().is_some()
516+
}
517+
485518
/// Has the `RMain` singleton completed initialization.
486519
///
487520
/// This can return true when R might still not have finished starting up.
@@ -545,38 +578,6 @@ impl RMain {
545578
thread.id() == unsafe { R_MAIN_THREAD_ID.unwrap() }
546579
}
547580

548-
/// Completes the kernel's initialization
549-
pub fn complete_initialization(&mut self) {
550-
if self.initializing {
551-
let version = unsafe {
552-
let version = Rf_findVarInFrame(R_BaseNamespace, r_symbol!("R.version.string"));
553-
RObject::new(version).to::<String>().unwrap()
554-
};
555-
556-
// Initial input and continuation prompts
557-
let input_prompt: String = harp::get_option("prompt").try_into().unwrap();
558-
let continuation_prompt: String = harp::get_option("continue").try_into().unwrap();
559-
560-
let kernel_info = KernelInfo {
561-
version: version.clone(),
562-
banner: self.banner_output.clone(),
563-
input_prompt: Some(input_prompt),
564-
continuation_prompt: Some(continuation_prompt),
565-
};
566-
567-
log::info!("Sending kernel info: {version}");
568-
self.kernel_init_tx.broadcast(kernel_info);
569-
570-
// Internal initialisation flag, should only be used on the R thread
571-
self.initializing = false;
572-
573-
// Used as thread-safe initialisation flag
574-
R_INIT.set(()).unwrap();
575-
} else {
576-
log::warn!("Initialization already complete!");
577-
}
578-
}
579-
580581
/// Provides read-only access to `iopub_tx`
581582
pub fn get_iopub_tx(&self) -> &Sender<IOPubMessage> {
582583
&self.iopub_tx
@@ -1323,7 +1324,7 @@ This is a Positron limitation we plan to fix. In the meantime, you can:
13231324
Stream::Stderr
13241325
};
13251326

1326-
if self.initializing {
1327+
if !RMain::is_r_initialized() {
13271328
// During init, consider all output to be part of the startup banner
13281329
self.banner_output.push_str(&content);
13291330
return;

0 commit comments

Comments
 (0)