@@ -32,7 +32,6 @@ use amalthea::wire::update_display_data::UpdateDisplayData;
32
32
use anyhow:: anyhow;
33
33
use base64:: engine:: general_purpose;
34
34
use base64:: Engine ;
35
- use crossbeam:: channel:: Receiver ;
36
35
use crossbeam:: channel:: Select ;
37
36
use crossbeam:: channel:: Sender ;
38
37
use harp:: exec:: RFunction ;
@@ -45,7 +44,7 @@ use libr::SEXP;
45
44
use serde_json:: json;
46
45
use stdext:: result:: ResultOrLog ;
47
46
use stdext:: unwrap;
48
- use tokio:: task :: yield_now ;
47
+ use tokio:: sync :: mpsc :: UnboundedReceiver as AsyncUnboundedReceiver ;
49
48
use uuid:: Uuid ;
50
49
51
50
use crate :: interface:: RMain ;
@@ -69,40 +68,35 @@ const POSITRON_PLOT_CHANNEL_ID: &str = "positron.plot";
69
68
pub ( crate ) fn init_graphics_device (
70
69
comm_manager_tx : Sender < CommManagerEvent > ,
71
70
iopub_tx : Sender < IOPubMessage > ,
72
- graphics_device_rx : Receiver < GraphicsDeviceNotification > ,
71
+ graphics_device_rx : AsyncUnboundedReceiver < GraphicsDeviceNotification > ,
73
72
) {
74
73
DEVICE_CONTEXT . set ( DeviceContext :: new ( comm_manager_tx, iopub_tx) ) ;
75
74
76
75
// Launch an R thread task to process messages from the frontend
77
76
r_task:: spawn_interrupt ( || async move { process_notifications ( graphics_device_rx) . await } ) ;
78
77
}
79
78
80
- async fn process_notifications ( graphics_device_rx : Receiver < GraphicsDeviceNotification > ) {
79
+ async fn process_notifications (
80
+ mut graphics_device_rx : AsyncUnboundedReceiver < GraphicsDeviceNotification > ,
81
+ ) {
81
82
log:: trace!( "Now listening for graphics device notifications" ) ;
82
83
83
84
loop {
84
- let mut i = 0 ;
85
-
86
- while let Ok ( notification) = graphics_device_rx. try_recv ( ) {
85
+ while let Some ( notification) = graphics_device_rx. recv ( ) . await {
87
86
log:: trace!( "Got graphics device notification: {notification:#?}" ) ;
88
- i = i + 1 ;
89
87
90
88
match notification {
91
89
GraphicsDeviceNotification :: DidChangePlotRenderSettings ( plot_render_settings) => {
90
+ // Safety: Note that `DEVICE_CONTEXT` is accessed at
91
+ // interrupt time. Other methods in this file should be
92
+ // written in accordance and avoid causing R interrupt
93
+ // checks while they themselves access the device.
92
94
DEVICE_CONTEXT . with_borrow ( |ctx| {
93
95
ctx. current_render_settings . replace ( plot_render_settings)
94
96
} ) ;
95
97
} ,
96
98
}
97
-
98
- // Yield regularly to the R thread when something went wrong on the
99
- // frontend side and is spamming messages
100
- if i >= 5 {
101
- break ;
102
- }
103
99
}
104
-
105
- yield_now ( ) . await ;
106
100
}
107
101
}
108
102
0 commit comments