@@ -370,72 +370,82 @@ public struct IORing: ~Copyable {
370370 // All throws need to be before initializing ivars here to avoid
371371 // "error: conditional initialization or destruction of noncopyable types is not supported;
372372 // this variable must be consistently in an initialized or uninitialized state through every code path"
373- features = Features ( rawValue: params. features)
374- ringDescriptor = tmpRingDescriptor
375- ringPtr = tmpRingPtr
376- ringSize = tmpRingSize
377- submissionRingPtr = tmpSQPtr
378- submissionRingSize = tmpSQSize
379- completionRingPtr = tmpCQPtr
380- completionRingSize = tmpCQSize
381-
382- _registeredFiles = [ ]
383- _registeredBuffers = [ ]
384- submissionRing = SQRing (
373+
374+ // Pre-compute values to avoid accessing partially initialized state
375+ let ringBasePtr = tmpRingPtr ?? tmpSQPtr!
376+ let completionBasePtr = tmpRingPtr ?? tmpCQPtr!
377+
378+ let submissionRing = SQRing (
385379 kernelHead: UnsafePointer < Atomic < UInt32 > > (
386- ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. head)
380+ ringBasePtr . advanced ( by: params. sq_off. head)
387381 . assumingMemoryBound ( to: Atomic< UInt32> . self )
388382 ) ,
389383 kernelTail: UnsafePointer < Atomic < UInt32 > > (
390- ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. tail)
384+ ringBasePtr . advanced ( by: params. sq_off. tail)
391385 . assumingMemoryBound ( to: Atomic< UInt32> . self )
392386 ) ,
393387 userTail: 0 , // no requests yet
394- ringMask: ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. ring_mask)
388+ ringMask: ringBasePtr . advanced ( by: params. sq_off. ring_mask)
395389 . assumingMemoryBound ( to: UInt32 . self) . pointee,
396390 flags: UnsafePointer < Atomic < UInt32 > > (
397- ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. flags)
391+ ringBasePtr . advanced ( by: params. sq_off. flags)
398392 . assumingMemoryBound ( to: Atomic< UInt32> . self )
399393 ) ,
400394 array: UnsafeMutableBufferPointer (
401- start: ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. array)
395+ start: ringBasePtr . advanced ( by: params. sq_off. array)
402396 . assumingMemoryBound ( to: UInt32 . self) ,
403397 count: Int (
404- ( ringPtr ?? submissionRingPtr! ) . advanced ( by: params. sq_off. ring_entries)
398+ ringBasePtr . advanced ( by: params. sq_off. ring_entries)
405399 . assumingMemoryBound ( to: UInt32 . self) . pointee)
406400 )
407401 )
408-
409- // fill submission ring array with 1:1 map to underlying SQEs
410- for i in 0 ..< submissionRing. array. count {
411- submissionRing. array [ i] = UInt32 ( i)
412- }
413-
414- submissionQueueEntries = UnsafeMutableBufferPointer (
415- start: sqes. assumingMemoryBound ( to: io_uring_sqe. self) ,
416- count: Int ( params. sq_entries)
417- )
418-
419- completionRing = CQRing (
402+
403+ let completionRing = CQRing (
420404 kernelHead: UnsafePointer < Atomic < UInt32 > > (
421- ( ringPtr ?? completionRingPtr! ) . advanced ( by: params. cq_off. head)
405+ completionBasePtr . advanced ( by: params. cq_off. head)
422406 . assumingMemoryBound ( to: Atomic< UInt32> . self )
423407 ) ,
424408 kernelTail: UnsafePointer < Atomic < UInt32 > > (
425- ( ringPtr ?? completionRingPtr! ) . advanced ( by: params. cq_off. tail)
409+ completionBasePtr . advanced ( by: params. cq_off. tail)
426410 . assumingMemoryBound ( to: Atomic< UInt32> . self )
427411 ) ,
428- ringMask: ( ringPtr ?? completionRingPtr! ) . advanced ( by: params. cq_off. ring_mask)
412+ ringMask: completionBasePtr . advanced ( by: params. cq_off. ring_mask)
429413 . assumingMemoryBound ( to: UInt32 . self) . pointee,
430414 cqes: UnsafeBufferPointer (
431- start: ( ringPtr ?? completionRingPtr! ) . advanced ( by: params. cq_off. cqes)
415+ start: completionBasePtr . advanced ( by: params. cq_off. cqes)
432416 . assumingMemoryBound ( to: io_uring_cqe. self) ,
433417 count: Int (
434- ( ringPtr ?? completionRingPtr! ) . advanced ( by: params. cq_off. ring_entries)
418+ completionBasePtr . advanced ( by: params. cq_off. ring_entries)
435419 . assumingMemoryBound ( to: UInt32 . self) . pointee)
436420 )
437421 )
422+
423+ let submissionQueueEntries = UnsafeMutableBufferPointer (
424+ start: sqes. assumingMemoryBound ( to: io_uring_sqe. self) ,
425+ count: Int ( params. sq_entries)
426+ )
427+
428+ // Now initialize all stored properties
429+ self . features = Features ( rawValue: params. features)
430+ self . ringDescriptor = tmpRingDescriptor
431+ self . ringPtr = tmpRingPtr
432+ self . ringSize = tmpRingSize
433+ self . submissionRingPtr = tmpSQPtr
434+ self . submissionRingSize = tmpSQSize
435+ self . completionRingPtr = tmpCQPtr
436+ self . completionRingSize = tmpCQSize
437+ self . _registeredFiles = [ ]
438+ self . _registeredBuffers = [ ]
439+ self . submissionRing = submissionRing
440+ self . completionRing = completionRing
441+ self . submissionQueueEntries = submissionQueueEntries
438442 self . ringFlags = params. flags
443+
444+ // fill submission ring array with 1:1 map to underlying SQEs
445+ // (happens after all properties are initialized)
446+ for i in 0 ..< self . submissionRing. array. count {
447+ self . submissionRing. array [ i] = UInt32 ( i)
448+ }
439449 }
440450
441451 @inlinable
0 commit comments