Skip to content

Commit 8de7ebb

Browse files
committed
Use r_task() in more places
1 parent 70780cf commit 8de7ebb

File tree

10 files changed

+60
-38
lines changed

10 files changed

+60
-38
lines changed

crates/ark/src/data_viewer/r_data_viewer.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use crossbeam::channel::Sender;
1414
use harp::exec::RFunction;
1515
use harp::exec::RFunctionExt;
1616
use harp::object::RObject;
17-
use harp::r_lock;
1817
use harp::utils::r_assert_length;
1918
use harp::utils::r_is_data_frame;
2019
use harp::utils::r_is_matrix;
@@ -44,6 +43,7 @@ use crate::data_viewer::message::DataViewerMessageRequest;
4443
use crate::data_viewer::message::DataViewerMessageResponse;
4544
use crate::data_viewer::message::DataViewerRowRequest;
4645
use crate::data_viewer::message::DataViewerRowResponse;
46+
use crate::r_task;
4747

4848
pub struct RDataViewer {
4949
title: String,
@@ -195,7 +195,7 @@ impl DataSet {
195195
}
196196

197197
pub fn from_object(id: String, title: String, object: RObject) -> Result<Self, anyhow::Error> {
198-
r_lock! {
198+
r_task(|| unsafe {
199199
let row_count = {
200200
if r_is_data_frame(*object) {
201201
let row_names = Rf_getAttrib(*object, R_RowNamesSymbol);
@@ -214,10 +214,10 @@ impl DataSet {
214214
Ok(Self {
215215
id: id.clone(),
216216
title: title.clone(),
217-
columns: columns,
218-
row_count: row_count
217+
columns,
218+
row_count,
219219
})
220-
}
220+
})
221221
}
222222

223223
fn slice_data(&self, start: usize, size: usize) -> Result<Vec<DataColumn>, anyhow::Error> {

crates/ark/src/interface.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ use harp::interrupts::RInterruptsSuspendedScope;
5252
use harp::lock::R_RUNTIME_LOCK;
5353
use harp::lock::R_RUNTIME_LOCK_COUNT;
5454
use harp::object::RObject;
55-
use harp::r_lock;
5655
use harp::r_safely;
5756
use harp::r_symbol;
5857
use harp::routines::r_register_routines;
@@ -75,6 +74,7 @@ use crate::kernel::Kernel;
7574
use crate::lsp::events::EVENTS;
7675
use crate::modules;
7776
use crate::plots::graphics_device;
77+
use crate::r_task;
7878
use crate::r_task::RTaskMain;
7979
use crate::request::debug_request_command;
8080
use crate::request::RRequest;
@@ -999,7 +999,7 @@ fn peek_execute_response(exec_count: u32) -> ExecuteResponse {
999999
data.insert("text/plain".to_string(), json!(""));
10001000

10011001
// Include HTML representation of data.frame
1002-
r_lock! {
1002+
r_task(|| unsafe {
10031003
let value = Rf_findVarInFrame(R_GlobalEnv, r_symbol!(".Last.value"));
10041004
if r_is_data_frame(value) {
10051005
match to_html(value) {
@@ -1010,7 +1010,7 @@ fn peek_execute_response(exec_count: u32) -> ExecuteResponse {
10101010
},
10111011
};
10121012
}
1013-
}
1013+
});
10141014

10151015
main.iopub_tx
10161016
.send(IOPubMessage::ExecuteResult(ExecuteResult {

crates/ark/src/lsp/backend.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use crate::lsp::indexer;
4747
use crate::lsp::signature_help::signature_help;
4848
use crate::lsp::statement_range;
4949
use crate::lsp::symbols;
50+
use crate::r_task;
5051
use crate::request::KernelRequest;
5152

5253
#[macro_export]
@@ -372,7 +373,16 @@ impl LanguageServer for Backend {
372373

373374
log::info!("Completion context: {:#?}", context);
374375

375-
// add session completions
376+
// FIXME: Use `r_task()`
377+
// rustc [E0277]: `*const c_void` cannot be shared between threads safely
378+
// within `completions::CompletionContext<'_>`, the trait `Sync` is not implemented for `*const c_void`
379+
// required for `&completions::CompletionContext<'_>` to implement `Send`
380+
// rustc [E0277]: `*const tree_sitter::ffi::TSTree` cannot be shared between threads safely
381+
// within `completions::CompletionContext<'_>`, the trait `Sync` is not implemented for `*const tree_sitter::ffi::TSTree`
382+
// required for `&completions::CompletionContext<'_>` to implement `Send`
383+
// rustc [E0277]: required because it's used within this closure
384+
385+
// Add session completions
376386
let result = r_lock! { append_session_completions(&context, &mut completions) };
377387
if let Err(error) = result {
378388
error!("{:?}", error);
@@ -444,9 +454,7 @@ impl LanguageServer for Backend {
444454
});
445455

446456
// Try resolving the completion item
447-
let result = r_lock! {
448-
resolve_completion_item(&mut item, &data)
449-
};
457+
let result = r_task(|| unsafe { resolve_completion_item(&mut item, &data) });
450458

451459
// Handle error case
452460
unwrap!(result, Err(error) => {
@@ -474,6 +482,16 @@ impl LanguageServer for Backend {
474482
return Ok(None);
475483
});
476484

485+
// FIXME: Use `r_task()`
486+
// rustc [E0277]: required by a bound introduced by this call
487+
// rustc [E0277]: `*const tree_sitter::ffi::TSTree` cannot be shared between threads safely
488+
// within `completions::CompletionContext<'_>`, the trait `Sync` is not implemented for `*const tree_sitter::ffi::TSTree`
489+
// required for `&completions::CompletionContext<'_>` to implement `Send`
490+
// rustc [E0277]: `*const c_void` cannot be shared between threads safely
491+
// within `completions::CompletionContext<'_>`, the trait `Sync` is not implemented for `*const c_void`
492+
// required for `&completions::CompletionContext<'_>` to implement `Send`
493+
// rustc [E0277]: required because it's used within this closure
494+
477495
// request hover information
478496
let result = r_lock! {
479497
hover(&document, &context)
@@ -508,9 +526,7 @@ impl LanguageServer for Backend {
508526
let position = params.text_document_position_params.position;
509527

510528
// request signature help
511-
let result = r_lock! {
512-
signature_help(document.value(), &position)
513-
};
529+
let result = r_task(|| unsafe { signature_help(document.value(), &position) });
514530

515531
// unwrap errors
516532
let result = unwrap!(result, Err(error) => {

crates/ark/src/lsp/diagnostics.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use tree_sitter::Node;
3434
use crate::lsp::backend::Backend;
3535
use crate::lsp::documents::Document;
3636
use crate::lsp::indexer;
37+
use crate::r_task;
3738
use crate::Range;
3839

3940
#[derive(Clone)]
@@ -148,11 +149,10 @@ fn generate_diagnostics(doc: &Document) -> Vec<Diagnostic> {
148149
_ => {},
149150
});
150151

151-
r_lock! {
152+
r_task(|| unsafe {
152153
// Get the set of symbols currently in scope.
153154
let mut envir = R_GlobalEnv;
154155
while envir != R_EmptyEnv {
155-
156156
// List symbol names in this environment.
157157
let mut protect = RProtect::new();
158158
let objects = protect.add(R_lsInternal(envir, 1));
@@ -185,7 +185,7 @@ fn generate_diagnostics(doc: &Document) -> Vec<Diagnostic> {
185185
context.installed_packages.insert(name);
186186
}
187187
}
188-
}
188+
});
189189

190190
// Start iterating through the nodes.
191191
let root = doc.ast.root_node();
@@ -638,6 +638,12 @@ impl<'a> TreeSitterCall<'a> {
638638
}
639639
}
640640

641+
// FIXME: Can't directly switch to `r_task()`
642+
// rustc [E0277]: `*const tree_sitter::ffi::TSTree` cannot be shared between threads safely
643+
// within `tree_sitter::Node<'_>`, the trait `Sync` is not implemented for `*const tree_sitter::ffi::TSTree`
644+
// required for `&tree_sitter::Node<'_>` to implement `Send`
645+
// rustc [E0277]: `*const c_void` cannot be shared between threads safely
646+
641647
fn recurse_call_arguments_custom(
642648
node: Node,
643649
context: &mut DiagnosticContext,

crates/ark/src/modules.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::time::Duration;
1414
use harp::exec::RFunction;
1515
use harp::exec::RFunctionExt;
1616
use harp::protect::RProtect;
17-
use harp::r_lock;
1817
use harp::r_string;
1918
use harp::r_symbol;
2019
use libR_sys::*;
@@ -23,6 +22,8 @@ use stdext::spawn;
2322
use stdext::unwrap;
2423
use stdext::unwrap::IntoResult;
2524

25+
use crate::r_task;
26+
2627
// We use a set of three environments for the functions exposed to
2728
// the R session. The environment chain is:
2829
//
@@ -92,11 +93,11 @@ impl RModuleWatcher {
9293
for (path, oldmeta) in self.cache.iter_mut() {
9394
let newmeta = path.metadata()?;
9495
if oldmeta.modified()? != newmeta.modified()? {
95-
r_lock! {
96-
if let Err(error) = import(path) {
97-
log::error!("{}", error);
96+
r_task(|| {
97+
if let Err(error) = unsafe { import(path) } {
98+
log::error!("{error:?}");
9899
}
99-
};
100+
});
100101
*oldmeta = newmeta;
101102
}
102103
}

crates/ark/src/plots/graphics_device.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ use crossbeam::channel::Select;
4242
use crossbeam::channel::Sender;
4343
use harp::exec::RFunction;
4444
use harp::exec::RFunctionExt;
45-
use harp::r_lock;
4645
use libR_sys::*;
4746
use once_cell::sync::Lazy;
4847
use serde_json::json;
@@ -53,6 +52,7 @@ use uuid::Uuid;
5352
use crate::plots::message::PlotMessageInput;
5453
use crate::plots::message::PlotMessageOutput;
5554
use crate::plots::message::PlotMessageOutputImage;
55+
use crate::r_task;
5656

5757
const POSITRON_PLOT_CHANNEL_ID: &str = "positron.plot";
5858

@@ -364,15 +364,15 @@ impl DeviceContext {
364364
// TODO: Is it possible to do this without writing to file; e.g. could
365365
// we instead write to a connection or something else?
366366
self._rendering = true;
367-
let image_path = r_lock! {
367+
let image_path = r_task(|| unsafe {
368368
RFunction::from(".ps.graphics.renderPlot")
369369
.param("id", plot_id)
370370
.param("width", width)
371371
.param("height", height)
372372
.param("dpr", pixel_ratio)
373373
.call()?
374374
.to::<String>()
375-
};
375+
});
376376
self._rendering = false;
377377

378378
let image_path = unwrap!(image_path, Err(error) => {

crates/ark/src/shell.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ use crossbeam::channel::Sender;
4242
use harp::exec::r_parse_vector;
4343
use harp::exec::ParseResult;
4444
use harp::object::RObject;
45-
use harp::r_lock;
4645
use libR_sys::*;
4746
use log::*;
4847
use serde_json::json;
@@ -54,6 +53,7 @@ use crate::frontend::frontend::PositronFrontend;
5453
use crate::interface::KernelInfo;
5554
use crate::kernel::Kernel;
5655
use crate::plots::graphics_device;
56+
use crate::r_task;
5757
use crate::request::KernelRequest;
5858
use crate::request::RRequest;
5959

@@ -221,9 +221,7 @@ impl ShellHandler for Shell {
221221
&self,
222222
req: &IsCompleteRequest,
223223
) -> Result<IsCompleteReply, Exception> {
224-
r_lock! {
225-
self.handle_is_complete_request_impl(req)
226-
}
224+
r_task(|| unsafe { self.handle_is_complete_request_impl(req) })
227225
}
228226

229227
/// Handles an ExecuteRequest by sending the code to the R execution thread
@@ -294,13 +292,11 @@ impl ShellHandler for Shell {
294292
/// Handles a request to open a new comm channel
295293
async fn handle_comm_open(&self, target: Comm, comm: CommSocket) -> Result<bool, Exception> {
296294
match target {
297-
Comm::Environment => {
298-
r_lock! {
299-
let global_env = RObject::view(R_GlobalEnv);
300-
REnvironment::start(global_env, comm.clone(), self.comm_manager_tx.clone());
301-
Ok(true)
302-
}
303-
},
295+
Comm::Environment => r_task(|| unsafe {
296+
let global_env = RObject::view(R_GlobalEnv);
297+
REnvironment::start(global_env, comm.clone(), self.comm_manager_tx.clone());
298+
Ok(true)
299+
}),
304300
Comm::FrontEnd => {
305301
// Create a frontend to wrap the comm channel we were just given. This starts
306302
// a thread that proxies messages to the frontend.

crates/ark/tests/environment.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ fn test_environment_list() {
4242
// against.
4343
start_r();
4444

45+
// TODO: Switch to `r_task()`
46+
4547
// Create a new environment for the test. We use a new, empty environment
4648
// (with the empty environment as its parent) so that each test in this
4749
// file can run independently.

crates/harp/src/exec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ mod tests {
530530

531531
#[test]
532532
fn test_threads() {
533+
// TODO: Switch to `r_task()`
533534
r_test_unlocked! {
534535

535536
// Spawn a bunch of threads that try to interact with R.

crates/harp/src/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl Drop for RObject {
216216

217217
// RObjects are not inherently thread-safe since they wrap a raw pointer, but we
218218
// allow them to be sent across threads because we require the acquisition of a
219-
// lock on the outer R interpreter (see `r_lock!`) before using them.
219+
// lock on the outer R interpreter (see `r_task()`) before using them.
220220
unsafe impl Send for RObject {}
221221
unsafe impl Sync for RObject {}
222222

0 commit comments

Comments
 (0)