@@ -18,7 +18,7 @@ use std::{
1818 LazyLock , OnceLock ,
1919 atomic:: { AtomicU8 , AtomicU16 , AtomicUsize , Ordering , fence} ,
2020 } ,
21- thread:: panicking,
21+ thread:: { AccessError , panicking} ,
2222 time:: { Instant , SystemTime } ,
2323} ;
2424
@@ -67,10 +67,13 @@ impl ShmCursor {
6767 }
6868}
6969
70+ thread_local ! {
71+ static SHM_CURSOR : RefCell <Option <ShmCursor >> = RefCell :: new( None ) ;
72+ }
73+
7074pub struct Client {
7175 encoded_payload : EncodedPayload ,
7276 shm_id : AtomicUsize ,
73- tls_shm_cursor : ThreadLocal < RefCell < ShmCursor > > ,
7477
7578 #[ cfg( target_os = "macos" ) ]
7679 posix_spawn_file_actions : OnceLock < libc:: posix_spawn_file_actions_t > ,
@@ -95,7 +98,6 @@ impl Client {
9598 Self {
9699 shm_id : AtomicUsize :: new ( 0 ) ,
97100 encoded_payload,
98- tls_shm_cursor : ThreadLocal :: new ( ) ,
99101 #[ cfg( target_os = "macos" ) ]
100102 posix_spawn_file_actions : OnceLock :: new ( ) ,
101103 }
@@ -118,26 +120,35 @@ impl Client {
118120 Ok ( ShmCursor { mmap_mut, position : 0 } )
119121 }
120122
121- fn with_shm_buf < R > (
123+ fn with_shm_buf (
122124 & self ,
123125 len : usize ,
124- f : impl FnOnce ( & mut [ u8 ] ) -> anyhow:: Result < R > ,
125- ) -> anyhow:: Result < R > {
126- let shm_buf =
127- self . tls_shm_cursor . get_or_try ( || io:: Result :: Ok ( RefCell :: new ( self . new_shm ( ) ?) ) ) ?;
126+ f : impl FnOnce ( & mut [ u8 ] ) -> anyhow:: Result < ( ) > ,
127+ ) -> anyhow:: Result < ( ) > {
128+ let result = SHM_CURSOR . try_with ( |shm_cursor| {
129+ let mut shm_cursor = shm_cursor. borrow_mut ( ) ;
130+ let shm_buf = if let Some ( some) = shm_cursor. as_mut ( ) {
131+ some
132+ } else {
133+ shm_cursor. insert ( self . new_shm ( ) ?)
134+ } ;
128135
129- let mut shm_buf = shm_buf. borrow_mut ( ) ;
130- if let Some ( buf) = shm_buf. advance ( len) {
131- f ( buf)
132- } else {
133- * shm_buf = self . new_shm ( ) ?;
134- let buf = shm_buf. advance ( len) . with_context ( || {
135- format ! (
136- "The requested buf ({}) is greater than the shm chunk size ({})" ,
137- len, SHM_CHUNK_SIZE
138- )
139- } ) ?;
140- f ( buf)
136+ if let Some ( buf) = shm_buf. advance ( len) {
137+ f ( buf)
138+ } else {
139+ * shm_buf = self . new_shm ( ) ?;
140+ let buf = shm_buf. advance ( len) . with_context ( || {
141+ format ! (
142+ "The requested buf ({}) is greater than the shm chunk size ({})" ,
143+ len, SHM_CHUNK_SIZE
144+ )
145+ } ) ?;
146+ f ( buf)
147+ }
148+ } ) ;
149+ match result {
150+ Ok ( ok) => ok,
151+ Err ( _) => Ok ( ( ) ) , // Ignore AccessError. TODO(fix): handle AccessError
141152 }
142153 }
143154
@@ -290,11 +301,14 @@ fn init_client() {
290301 let Some ( client) = global_client ( ) else {
291302 return ;
292303 } ;
293- if let Some ( shm_cursor ) = client . tls_shm_cursor . get ( ) {
294- // Move the shm cursor to the end so that the next time it's used it will be reset .
304+ let _ = SHM_CURSOR . try_with ( |shm_cursor| {
305+ // Move the shm cursor to the end so that the next time it's used a new one will be created .
295306 let mut shm_cursor = shm_cursor. borrow_mut ( ) ;
307+ let Some ( shm_cursor) = shm_cursor. as_mut ( ) else {
308+ return ;
309+ } ;
296310 shm_cursor. position = shm_cursor. mmap_mut . len ( ) ;
297- }
311+ } ) ;
298312 }
299313 let ret = unsafe { pthread_atfork ( None , None , Some ( reset_shm_atfork) ) } ;
300314 if ret != 0 {
0 commit comments