Diagnosed Arc sharing issue in SocketBox cloning - complex race condition
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -65,7 +65,13 @@ impl Clone for SocketBox {
|
|||||||
};
|
};
|
||||||
let original_arc_ptr = Arc::as_ptr(&self.is_server) as usize;
|
let original_arc_ptr = Arc::as_ptr(&self.is_server) as usize;
|
||||||
let cloned_arc_ptr = Arc::as_ptr(&cloned.is_server) as usize;
|
let cloned_arc_ptr = Arc::as_ptr(&cloned.is_server) as usize;
|
||||||
let is_server_value = *self.is_server.lock().unwrap();
|
let is_server_value = match self.is_server.lock() {
|
||||||
|
Ok(guard) => *guard,
|
||||||
|
Err(_) => {
|
||||||
|
println!("🚨 SocketBox::clone() - Failed to lock is_server mutex!");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
println!("🔄 SocketBox::clone() - original Box ID: {}, cloned Box ID: {}, Arc ptr: {:x} -> {:x}, is_server: {}",
|
println!("🔄 SocketBox::clone() - original Box ID: {}, cloned Box ID: {}, Arc ptr: {:x} -> {:x}, is_server: {}",
|
||||||
self.base.id, cloned.base.id, original_arc_ptr, cloned_arc_ptr, is_server_value);
|
self.base.id, cloned.base.id, original_arc_ptr, cloned_arc_ptr, is_server_value);
|
||||||
cloned
|
cloned
|
||||||
@ -114,6 +120,10 @@ impl SocketBox {
|
|||||||
// Verify the value was actually set
|
// Verify the value was actually set
|
||||||
let verify_value = *is_server_guard;
|
let verify_value = *is_server_guard;
|
||||||
println!("✅ SocketBox::bind() - is_server set to true (Box ID: {}, Arc ptr: {:x}, verify: {})", self.base.id, arc_ptr, verify_value);
|
println!("✅ SocketBox::bind() - is_server set to true (Box ID: {}, Arc ptr: {:x}, verify: {})", self.base.id, arc_ptr, verify_value);
|
||||||
|
// Also verify it's readable immediately
|
||||||
|
drop(is_server_guard);
|
||||||
|
let reread_value = *self.is_server.lock().unwrap();
|
||||||
|
println!("🔍 SocketBox::bind() - reread value: {}", reread_value);
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("🚨 SocketBox::bind() - Failed to acquire is_server lock (Box ID: {})", self.base.id);
|
println!("🚨 SocketBox::bind() - Failed to acquire is_server lock (Box ID: {})", self.base.id);
|
||||||
@ -346,6 +356,11 @@ impl SocketBox {
|
|||||||
let arc_ptr = Arc::as_ptr(&self.is_server) as usize;
|
let arc_ptr = Arc::as_ptr(&self.is_server) as usize;
|
||||||
println!("🔍 SocketBox::is_server() called - returning {} (Box ID: {}, Arc ptr: {:x})",
|
println!("🔍 SocketBox::is_server() called - returning {} (Box ID: {}, Arc ptr: {:x})",
|
||||||
is_server_value, self.base.id, arc_ptr);
|
is_server_value, self.base.id, arc_ptr);
|
||||||
|
// Double-check by re-reading
|
||||||
|
let double_check = *self.is_server.lock().unwrap();
|
||||||
|
if is_server_value != double_check {
|
||||||
|
println!("🚨 WARNING: is_server value changed between reads! {} -> {}", is_server_value, double_check);
|
||||||
|
}
|
||||||
Box::new(BoolBox::new(is_server_value))
|
Box::new(BoolBox::new(is_server_value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -467,7 +467,26 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
// SocketBox method calls
|
// SocketBox method calls
|
||||||
if let Some(socket_box) = obj_value.as_any().downcast_ref::<SocketBox>() {
|
if let Some(socket_box) = obj_value.as_any().downcast_ref::<SocketBox>() {
|
||||||
return self.execute_socket_method(socket_box, method, arguments);
|
let result = self.execute_socket_method(socket_box, method, arguments)?;
|
||||||
|
|
||||||
|
// 🔧 FIX: Update stored variable for stateful SocketBox methods
|
||||||
|
// These methods modify the SocketBox internal state, so we need to update
|
||||||
|
// the stored local variable to ensure subsequent accesses get the updated state
|
||||||
|
if matches!(method, "bind" | "connect" | "close") {
|
||||||
|
if let ASTNode::Variable { name, .. } = object {
|
||||||
|
if let Some(stored_var) = self.local_vars.get_mut(name) {
|
||||||
|
// Replace the stored instance with the modified one
|
||||||
|
let updated_instance = socket_box.clone();
|
||||||
|
let new_box_id = updated_instance.box_id();
|
||||||
|
let new_is_server = updated_instance.is_server().to_string_box().value == "true";
|
||||||
|
*stored_var = Box::new(updated_instance);
|
||||||
|
println!("🔧 Updated local variable '{}' after '{}' - new Box ID: {}, is_server: {}",
|
||||||
|
name, method, new_box_id, new_is_server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPServerBox method calls
|
// HTTPServerBox method calls
|
||||||
|
|||||||
24
test_arc_sharing.nyash
Normal file
24
test_arc_sharing.nyash
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Test Arc sharing issue
|
||||||
|
static box Main {
|
||||||
|
main() {
|
||||||
|
print("🔬 Testing Arc sharing...")
|
||||||
|
|
||||||
|
local socket1
|
||||||
|
socket1 = new SocketBox()
|
||||||
|
|
||||||
|
local socket2
|
||||||
|
socket2 = socket1 // This should clone
|
||||||
|
|
||||||
|
print("Before bind - socket1.isServer(): " + socket1.isServer().toString())
|
||||||
|
print("Before bind - socket2.isServer(): " + socket2.isServer().toString())
|
||||||
|
|
||||||
|
socket1.bind("127.0.0.1", 8080)
|
||||||
|
|
||||||
|
print("After bind - socket1.isServer(): " + socket1.isServer().toString())
|
||||||
|
print("After bind - socket2.isServer(): " + socket2.isServer().toString())
|
||||||
|
|
||||||
|
socket1.close()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
23
test_socket_simple.nyash
Normal file
23
test_socket_simple.nyash
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Simple test for SocketBox state sharing
|
||||||
|
static box Main {
|
||||||
|
main() {
|
||||||
|
print("🧪 Testing SocketBox state sharing...")
|
||||||
|
|
||||||
|
local socket
|
||||||
|
socket = new SocketBox()
|
||||||
|
|
||||||
|
print("Initial isServer: " + socket.isServer().toString())
|
||||||
|
|
||||||
|
local bindOk
|
||||||
|
bindOk = socket.bind("127.0.0.1", 8080)
|
||||||
|
print("Bind result: " + bindOk.toString())
|
||||||
|
|
||||||
|
print("After bind isServer: " + socket.isServer().toString())
|
||||||
|
|
||||||
|
local closeOk
|
||||||
|
closeOk = socket.close()
|
||||||
|
print("Close result: " + closeOk.toString())
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user