@@ -20,10 +20,10 @@ def self.supported?
2020 @supported
2121 end
2222
23- # POSIX shared memory constants
24- O_CREAT = 0x0200
25- O_EXCL = 0x0800
26- O_RDWR = 0x0002
23+ # Use Ruby's File constants instead of hardcoded values for cross-platform compatibility
24+ O_CREAT = IO :: CREAT
25+ O_EXCL = IO :: EXCL
26+ O_RDWR = IO :: RDWR
2727
2828 # Load system functions
2929 LIBC = Fiddle . dlopen ( nil )
@@ -84,13 +84,11 @@ def self.create_handle(size)
8484 # Generate a unique name using multiple entropy sources to avoid collisions
8585 # in high-concurrency situations
8686 max_attempts = 8
87+ last_error = nil
8788
8889 max_attempts . times do
89- # Combine multiple entropy sources for uniqueness:
90- # - Process PID
91- # - Thread object ID (unique per thread)
92- # - Microsecond timestamp
93- shm_name = "/#{ Process . pid } _#{ Fiber . current . object_id } _#{ Time . now . usec } "
90+ # The most portable maximum length for a POSIX shared memory name is 14 characters:
91+ shm_name = "/#{ SecureRandom . hex ( 7 ) } "
9492
9593 # Create shared memory object with O_EXCL to ensure uniqueness
9694 shm_fd = SHM_OPEN . call ( shm_name , O_CREAT | O_EXCL | O_RDWR , 0600 )
@@ -100,20 +98,27 @@ def self.create_handle(size)
10098 if FTRUNCATE . call ( shm_fd , size ) == 0
10199 # Create IO object from file descriptor
102100 io = ::IO . for_fd ( shm_fd , autoclose : true )
103-
101+
104102 # Return Handle that manages both IO and cleanup
105103 return Handle . new ( io , shm_name , size )
106104 else
107105 # ftruncate failed, clean up
108106 SHM_UNLINK . call ( shm_name )
109107 raise IO ::Memory ::MemoryError , "Failed to set shared memory size to #{ size } !"
110108 end
109+ else
110+ # Store the error for potential debugging
111+ last_error = Fiddle . last_error
111112 end
112113 # If we get here, shm_open failed (likely name collision), try again with new name
113114 end
114115
115- # If we've exhausted all attempts
116- raise IO ::Memory ::MemoryError , "Failed to create shared memory object after #{ max_attempts } attempts!"
116+ # If we've exhausted all attempts:
117+ if last_error
118+ cause = SystemCallError . new ( last_error )
119+ end
120+
121+ raise IO ::Memory ::MemoryError , "Failed to create shared memory object after #{ max_attempts } attempts!" , cause : cause
117122 end
118123
119124 @supported = true
0 commit comments