14
14
15
15
use std:: {
16
16
io,
17
+ mem:: MaybeUninit ,
17
18
os:: windows:: io:: { AsRawHandle , FromRawHandle , OwnedHandle , RawHandle } ,
18
19
time:: Duration ,
19
20
} ;
20
21
21
- use compio_buf:: arrayvec:: ArrayVec ;
22
22
use compio_log:: * ;
23
23
use windows_sys:: Win32 :: {
24
24
Foundation :: {
@@ -55,6 +55,8 @@ struct CompletionPort {
55
55
}
56
56
57
57
impl CompletionPort {
58
+ pub const DEFAULT_CAPACITY : usize = 1024 ;
59
+
58
60
pub fn new ( ) -> io:: Result < Self > {
59
61
let port = syscall ! ( BOOL , CreateIoCompletionPort ( INVALID_HANDLE_VALUE , 0 , 0 , 1 ) ) ?;
60
62
trace ! ( "new iocp handle: {port}" ) ;
@@ -104,10 +106,8 @@ impl CompletionPort {
104
106
pub fn poll_raw (
105
107
& self ,
106
108
timeout : Option < Duration > ,
107
- ) -> io:: Result < impl Iterator < Item = OVERLAPPED_ENTRY > > {
108
- const DEFAULT_CAPACITY : usize = 1024 ;
109
-
110
- let mut entries = ArrayVec :: < OVERLAPPED_ENTRY , { DEFAULT_CAPACITY } > :: new ( ) ;
109
+ entries : & mut [ MaybeUninit < OVERLAPPED_ENTRY > ] ,
110
+ ) -> io:: Result < usize > {
111
111
let mut recv_count = 0 ;
112
112
let timeout = match timeout {
113
113
Some ( timeout) => timeout. as_millis ( ) as u32 ,
@@ -117,17 +117,16 @@ impl CompletionPort {
117
117
BOOL ,
118
118
GetQueuedCompletionStatusEx (
119
119
self . port. as_raw_handle( ) as _,
120
- entries. as_mut_ptr( ) ,
121
- DEFAULT_CAPACITY as _,
120
+ entries. as_mut_ptr( ) . cast ( ) ,
121
+ entries . len ( ) as _,
122
122
& mut recv_count,
123
123
timeout,
124
124
0
125
125
)
126
126
) ?;
127
127
trace ! ( "recv_count: {recv_count}" ) ;
128
- unsafe { entries. set_len ( recv_count as _ ) } ;
129
128
130
- Ok ( entries . into_iter ( ) )
129
+ Ok ( recv_count as _ )
131
130
}
132
131
133
132
// If current_driver is specified, any entry that doesn't belong the driver will
@@ -137,7 +136,10 @@ impl CompletionPort {
137
136
timeout : Option < Duration > ,
138
137
current_driver : Option < RawFd > ,
139
138
) -> io:: Result < impl Iterator < Item = Entry > > {
140
- Ok ( self . poll_raw ( timeout) ?. filter_map ( move |entry| {
139
+ let mut entries = Vec :: with_capacity ( Self :: DEFAULT_CAPACITY ) ;
140
+ let len = self . poll_raw ( timeout, entries. spare_capacity_mut ( ) ) ?;
141
+ unsafe { entries. set_len ( len) } ;
142
+ Ok ( entries. into_iter ( ) . filter_map ( move |entry| {
141
143
// Any thin pointer is OK because we don't use the type of opcode.
142
144
let overlapped_ptr: * mut Overlapped = entry. lpOverlapped . cast ( ) ;
143
145
let overlapped = unsafe { & * overlapped_ptr } ;
0 commit comments