Skip to content

Commit bd58dc1

Browse files
authored
Merge pull request #94 from Shopify/ap.cached-module-id-atomic-fix-3
Fix for atomic issue
2 parents d602bd7 + a998f37 commit bd58dc1

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

api/src/lib.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ use shopify_function_wasm_api_core::{
2424
read::{ErrorCode, NanBox, Val, ValueRef},
2525
ContextPtr,
2626
};
27-
use std::{
28-
ptr::NonNull,
29-
sync::atomic::{AtomicPtr, AtomicUsize, Ordering},
30-
};
27+
use std::ptr::NonNull;
28+
#[cfg(target_pointer_width = "32")]
29+
use std::sync::atomic::{AtomicU64, Ordering};
30+
#[cfg(target_pointer_width = "64")]
31+
use std::sync::Mutex;
3132

3233
pub mod read;
3334
pub mod write;
@@ -242,17 +243,21 @@ impl InternedStringId {
242243
/// A mechanism for caching interned string IDs.
243244
pub struct CachedInternedStringId {
244245
value: &'static str,
245-
interned_string_id: AtomicUsize,
246-
context: AtomicPtr<std::ffi::c_void>,
246+
#[cfg(target_pointer_width = "32")]
247+
interned_string_id_and_context: AtomicU64,
248+
#[cfg(target_pointer_width = "64")]
249+
interned_string_id_and_context: Mutex<(usize, usize)>,
247250
}
248251

249252
impl CachedInternedStringId {
250253
/// Create a new cached interned string ID.
251254
pub const fn new(value: &'static str) -> Self {
252255
Self {
253256
value,
254-
interned_string_id: AtomicUsize::new(usize::MAX),
255-
context: AtomicPtr::new(std::ptr::null_mut()),
257+
#[cfg(target_pointer_width = "32")]
258+
interned_string_id_and_context: AtomicU64::new(u64::MAX),
259+
#[cfg(target_pointer_width = "64")]
260+
interned_string_id_and_context: Mutex::new((usize::MAX, usize::MAX)),
256261
}
257262
}
258263

@@ -266,15 +271,35 @@ impl CachedInternedStringId {
266271
self.load_from_context_ptr(value.context.as_ptr() as _)
267272
}
268273

274+
#[cfg(target_pointer_width = "32")]
275+
fn load_from_context_ptr(&self, context: ContextPtr) -> InternedStringId {
276+
let interned_string_id_and_context =
277+
self.interned_string_id_and_context.load(Ordering::Relaxed);
278+
if interned_string_id_and_context & (u32::MAX as u64) == context as u64 {
279+
InternedStringId((interned_string_id_and_context >> 32) as usize)
280+
} else {
281+
let id = unsafe {
282+
shopify_function_intern_utf8_str(context, self.value.as_ptr(), self.value.len())
283+
};
284+
let interned_string_id_and_context = ((id as u64) << 32) | (context as u64);
285+
self.interned_string_id_and_context
286+
.store(interned_string_id_and_context, Ordering::Relaxed);
287+
InternedStringId(id as usize)
288+
}
289+
}
290+
291+
#[cfg(target_pointer_width = "64")]
269292
fn load_from_context_ptr(&self, context: ContextPtr) -> InternedStringId {
270-
if self.context.load(Ordering::Relaxed) != context {
293+
let mut interned_string_id_and_context =
294+
self.interned_string_id_and_context.lock().unwrap();
295+
if interned_string_id_and_context.1 != context as usize {
271296
let id = unsafe {
272297
shopify_function_intern_utf8_str(context, self.value.as_ptr(), self.value.len())
273298
};
274-
self.interned_string_id.store(id, Ordering::Relaxed);
275-
self.context.store(context, Ordering::Relaxed);
299+
interned_string_id_and_context.0 = id;
300+
interned_string_id_and_context.1 = context as usize;
276301
}
277-
InternedStringId(self.interned_string_id.load(Ordering::Relaxed))
302+
InternedStringId(interned_string_id_and_context.0)
278303
}
279304
}
280305

0 commit comments

Comments
 (0)