From 825cdf84563b9f0bab545420200e505099aba262 Mon Sep 17 00:00:00 2001 From: usamoi Date: Sun, 3 Nov 2024 00:26:43 +0800 Subject: [PATCH] fix "fix fix shmem API on Windows" --- pgrx/src/atomics.rs | 5 ++++- pgrx/src/lwlock.rs | 10 +++++----- pgrx/src/shmem.rs | 25 +++++++++++-------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pgrx/src/atomics.rs b/pgrx/src/atomics.rs index 40e7705ff..af722f455 100644 --- a/pgrx/src/atomics.rs +++ b/pgrx/src/atomics.rs @@ -38,7 +38,10 @@ where } pub fn get(&self) -> &T { - unsafe { (*self.inner.get()).as_ref().expect("PgAtomic was not initialized") } + unsafe { + let shared = self.inner.get().read().as_ref().expect("PgAtomic was not initialized"); + shared + } } } diff --git a/pgrx/src/lwlock.rs b/pgrx/src/lwlock.rs index 0a3d613e9..c6e7827e5 100644 --- a/pgrx/src/lwlock.rs +++ b/pgrx/src/lwlock.rs @@ -53,18 +53,18 @@ impl PgLwLock { /// Obtain a shared lock (which comes with `&T` access) pub fn share(&self) -> PgLwLockShareGuard { unsafe { - let shared = *self.inner.get().as_ref().expect("PgLwLock was not initialized"); + let shared = self.inner.get().read().as_ref().expect("PgLwLock was not initialized"); pg_sys::LWLockAcquire((*shared).lock_ptr, pg_sys::LWLockMode::LW_SHARED); - PgLwLockShareGuard { data: &(*shared).data, lock: (*shared).lock_ptr } + PgLwLockShareGuard { data: &*(*shared).data.get(), lock: (*shared).lock_ptr } } } /// Obtain an exclusive lock (which comes with `&mut T` access) pub fn exclusive(&self) -> PgLwLockExclusiveGuard { unsafe { - let shared = *self.inner.get().as_ref().expect("PgLwLock was not initialized"); + let shared = self.inner.get().read().as_ref().expect("PgLwLock was not initialized"); pg_sys::LWLockAcquire((*shared).lock_ptr, pg_sys::LWLockMode::LW_EXCLUSIVE); - PgLwLockExclusiveGuard { data: &mut (*shared).data, lock: (*shared).lock_ptr } + PgLwLockExclusiveGuard { data: &mut *(*shared).data.get(), lock: (*shared).lock_ptr } } } @@ -77,7 +77,7 @@ impl PgLwLock { #[repr(C)] pub struct PgLwLockShared { - pub data: T, + pub data: UnsafeCell, pub lock_ptr: *mut pg_sys::LWLock, } diff --git a/pgrx/src/shmem.rs b/pgrx/src/shmem.rs index 2bdab6bcd..877c4f904 100644 --- a/pgrx/src/shmem.rs +++ b/pgrx/src/shmem.rs @@ -10,6 +10,7 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::lwlock::*; use crate::{pg_sys, PgAtomic}; +use std::cell::UnsafeCell; use std::hash::Hash; /// Custom types that want to participate in shared memory must implement this marker trait @@ -176,27 +177,26 @@ impl PgSharedMem { /// Must be run from the shared memory init hook, use for types which are guarded by a `LWLock` /// SAFETY: Must only be called from inside the Postgres shared memory init hook pub unsafe fn shmem_init_locked(lock: &PgLwLock) { - let mut found = false; unsafe { let shm_name = lock.name(); - let addin_shmem_init_lock: *mut pg_sys::LWLock = - &mut (*pg_sys::MainLWLockArray.add(21)).lock; + let addin_shmem_init_lock = &raw mut (*pg_sys::MainLWLockArray.add(21)).lock; pg_sys::LWLockAcquire(addin_shmem_init_lock, pg_sys::LWLockMode::LW_EXCLUSIVE); + let mut found = false; let fv_shmem = pg_sys::ShmemInitStruct( shm_name.as_ptr(), std::mem::size_of::>(), &mut found, - ) as *mut PgLwLockShared; - + ) + .cast::>(); if !found { fv_shmem.write(PgLwLockShared { - data: T::default(), + data: UnsafeCell::new(T::default()), lock_ptr: &raw mut (*pg_sys::GetNamedLWLockTranche(shm_name.as_ptr())).lock, }); } - lock.attach(fv_shmem); + lock.attach(fv_shmem); pg_sys::LWLockRelease(addin_shmem_init_lock); } } @@ -206,21 +206,18 @@ impl PgSharedMem { pub unsafe fn shmem_init_atomic(atomic: &PgAtomic) { unsafe { let shm_name = atomic.name(); - - let addin_shmem_init_lock: *mut pg_sys::LWLock = - &mut (*pg_sys::MainLWLockArray.add(21)).lock; + let addin_shmem_init_lock = &raw mut (*pg_sys::MainLWLockArray.add(21)).lock; + pg_sys::LWLockAcquire(addin_shmem_init_lock, pg_sys::LWLockMode::LW_EXCLUSIVE); let mut found = false; - pg_sys::LWLockAcquire(addin_shmem_init_lock, pg_sys::LWLockMode::LW_EXCLUSIVE); let fv_shmem = pg_sys::ShmemInitStruct(shm_name.as_ptr(), std::mem::size_of::(), &mut found) - as *mut T; - + .cast::(); if !found { fv_shmem.write(T::default()); } - atomic.attach(fv_shmem); + atomic.attach(fv_shmem); pg_sys::LWLockRelease(addin_shmem_init_lock); } }