-
Notifications
You must be signed in to change notification settings - Fork 242
[ISSUE #3517]⚡️Memory Management Fix for AtomicPtr-based Address Fields in HA Client #3518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -63,7 +63,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Default HA Client implementation using bytes crate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub struct DefaultHAClient { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Master HA address (atomic reference) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_ha_address: Arc<RwLock<Option<String>>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_ha_address: Arc<AtomicPtr<String>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Master address (atomic reference) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_address: Arc<AtomicPtr<String>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -120,7 +120,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let now = get_current_millis() as i64; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(ArcMut::new(Self { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_ha_address: Arc::new(RwLock::new(None)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_ha_address: Arc::new(AtomicPtr::default()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| master_address: Arc::new(AtomicPtr::default()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| socket_stream: Arc::new(RwLock::new(None)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| last_read_timestamp: AtomicI64::new(now), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -140,21 +140,15 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Update HA master address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub async fn update_ha_master_address(&self, new_addr: Option<String>) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut current_addr = self.master_ha_address.write().await; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let old_addr = current_addr.clone(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *current_addr = new_addr.clone(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "update master ha address, OLD: {:?} NEW: {:?}", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| old_addr, new_addr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Get HA master address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub async fn get_ha_master_address(&self) -> Option<String> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.master_ha_address.read().await.clone() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let addr_ptr = self.master_ha_address.load(Ordering::SeqCst); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !addr_ptr.is_null() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let address = unsafe { (*addr_ptr).clone() }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Some(address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Get master address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -688,7 +682,17 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn update_ha_master_address(&self, new_address: &str) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| todo!() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Safely free the old pointer before storing the new one | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let old_address = self.master_address.load(Ordering::SeqCst); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !old_address.is_null() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unsafe { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Convert the old pointer back into a Box to free the memory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let _ = Box::from_raw(old_address); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Store the new address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let new_address_ptr = Box::into_raw(Box::new(new_address.to_string())); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.master_address.store(new_address_ptr, Ordering::SeqCst); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
684
to
696
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical bug: Method is updating the wrong field! The Apply this fix: fn update_ha_master_address(&self, new_address: &str) {
// Safely free the old pointer before storing the new one
- let old_address = self.master_address.load(Ordering::SeqCst);
+ let old_address = self.master_ha_address.load(Ordering::SeqCst);
if !old_address.is_null() {
unsafe {
// Convert the old pointer back into a Box to free the memory
let _ = Box::from_raw(old_address);
}
}
// Store the new address
let new_address_ptr = Box::into_raw(Box::new(new_address.to_string()));
- self.master_address.store(new_address_ptr, Ordering::SeqCst);
+ self.master_ha_address.store(new_address_ptr, Ordering::SeqCst);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn get_master_address(&self) -> String { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading the old pointer and freeing it before storing the new one can introduce race conditions under concurrent access. Use
swapto atomically exchange the pointer (let old_ptr = self.master_address.swap(new_ptr, Ordering::SeqCst)) and then freeold_ptr.