@@ -191,25 +191,25 @@ type _TCP_INFO_v0 struct {
191
191
SynRetrans uint8
192
192
}
193
193
194
- func newFD (t testing.TB , h syscall.Handle , kind string , overlapped bool ) * poll.FD {
194
+ func newFD (t testing.TB , h syscall.Handle , kind string , overlapped , pollable bool ) * poll.FD {
195
195
fd := poll.FD {
196
196
Sysfd : h ,
197
197
IsStream : true ,
198
198
ZeroReadIsEOF : true ,
199
199
}
200
- err := fd .Init (kind , true )
200
+ err := fd .Init (kind , pollable )
201
201
if overlapped && err != nil {
202
202
// Overlapped file handles should not error.
203
203
t .Fatal (err )
204
- } else if ! overlapped && err == nil {
204
+ } else if ! overlapped && pollable && err == nil {
205
205
// Non-overlapped file handles should return an error but still
206
206
// be usable as sync handles.
207
207
t .Fatal ("expected error for non-overlapped file handle" )
208
208
}
209
209
return & fd
210
210
}
211
211
212
- func newFile (t testing.TB , name string , overlapped bool ) * poll.FD {
212
+ func newFile (t testing.TB , name string , overlapped , pollable bool ) * poll.FD {
213
213
namep , err := syscall .UTF16PtrFromString (name )
214
214
if err != nil {
215
215
t .Fatal (err )
@@ -230,7 +230,15 @@ func newFile(t testing.TB, name string, overlapped bool) *poll.FD {
230
230
t .Fatal (err )
231
231
}
232
232
})
233
- return newFD (t , h , "file" , overlapped )
233
+ typ , err := syscall .GetFileType (h )
234
+ if err != nil {
235
+ t .Fatal (err )
236
+ }
237
+ kind := "file"
238
+ if typ == syscall .FILE_TYPE_PIPE {
239
+ kind = "pipe"
240
+ }
241
+ return newFD (t , h , kind , overlapped , pollable )
234
242
}
235
243
236
244
var currentProces = sync .OnceValue (func () string {
@@ -240,8 +248,19 @@ var currentProces = sync.OnceValue(func() string {
240
248
241
249
var pipeCounter atomic.Uint64
242
250
243
- func newPipe (t testing.TB , overlapped , message bool ) (string , * poll.FD ) {
244
- name := `\\.\pipe\go-internal-poll-test-` + currentProces () + `-` + strconv .FormatUint (pipeCounter .Add (1 ), 10 )
251
+ func newBytePipe (t testing.TB , name string , overlapped , pollable bool ) * poll.FD {
252
+ return newPipe (t , name , false , overlapped , pollable )
253
+ }
254
+
255
+ func newMessagePipe (t testing.TB , name string , overlapped , pollable bool ) * poll.FD {
256
+ return newPipe (t , name , true , overlapped , pollable )
257
+ }
258
+
259
+ func pipeName () string {
260
+ return `\\.\pipe\go-internal-poll-test-` + currentProces () + `-` + strconv .FormatUint (pipeCounter .Add (1 ), 10 )
261
+ }
262
+
263
+ func newPipe (t testing.TB , name string , message , overlapped , pollable bool ) * poll.FD {
245
264
wname , err := syscall .UTF16PtrFromString (name )
246
265
if err != nil {
247
266
t .Fatal (err )
@@ -264,7 +283,7 @@ func newPipe(t testing.TB, overlapped, message bool) (string, *poll.FD) {
264
283
t .Fatal (err )
265
284
}
266
285
})
267
- return name , newFD (t , h , "pipe" , overlapped )
286
+ return newFD (t , h , "pipe" , overlapped , pollable )
268
287
}
269
288
270
289
func testReadWrite (t * testing.T , fdr , fdw * poll.FD ) {
@@ -341,54 +360,55 @@ func testPreadPwrite(t *testing.T, fdr, fdw *poll.FD) {
341
360
342
361
func TestFile (t * testing.T ) {
343
362
t .Parallel ()
344
- test := func (t * testing.T , r , w bool ) {
345
- t .Parallel ()
346
- name := filepath .Join (t .TempDir (), "foo" )
347
- rh := newFile (t , name , r )
348
- wh := newFile (t , name , w )
349
- testReadWrite (t , rh , wh )
350
- testPreadPwrite (t , rh , wh )
351
- }
352
- t .Run ("overlapped" , func (t * testing.T ) {
353
- test (t , true , true )
354
- })
355
- t .Run ("overlapped-read" , func (t * testing.T ) {
356
- test (t , true , false )
357
- })
358
- t .Run ("overlapped-write" , func (t * testing.T ) {
359
- test (t , false , true )
360
- })
361
- t .Run ("sync" , func (t * testing.T ) {
362
- test (t , false , false )
363
- })
363
+ tests := []struct {
364
+ name string
365
+ overlappedRead bool
366
+ overlappedWrite bool
367
+ pollable bool
368
+ }{
369
+ {"overlapped" , true , true , true },
370
+ {"overlapped-nonpollable" , true , true , false },
371
+ {"overlapped-read" , true , false , true },
372
+ {"overlapped-write" , false , true , true },
373
+ {"sync" , false , false , false },
374
+ {"sync-pollable" , false , false , true },
375
+ }
376
+ for _ , tt := range tests {
377
+ t .Run (tt .name , func (t * testing.T ) {
378
+ t .Parallel ()
379
+ name := filepath .Join (t .TempDir (), "foo" )
380
+ rh := newFile (t , name , tt .overlappedRead , tt .pollable )
381
+ wh := newFile (t , name , tt .overlappedWrite , tt .pollable )
382
+ testReadWrite (t , rh , wh )
383
+ testPreadPwrite (t , rh , wh )
384
+ })
385
+ }
364
386
}
365
387
366
388
func TestPipe (t * testing.T ) {
367
389
t .Parallel ()
368
- t .Run ("overlapped" , func (t * testing.T ) {
369
- t .Parallel ()
370
- name , pipe := newPipe (t , true , false )
371
- file := newFile (t , name , true )
372
- testReadWrite (t , pipe , file )
373
- })
374
- t .Run ("overlapped-write" , func (t * testing.T ) {
375
- t .Parallel ()
376
- name , pipe := newPipe (t , true , false )
377
- file := newFile (t , name , false )
378
- testReadWrite (t , file , pipe )
379
- })
380
- t .Run ("overlapped-read" , func (t * testing.T ) {
381
- t .Parallel ()
382
- name , pipe := newPipe (t , false , false )
383
- file := newFile (t , name , true )
384
- testReadWrite (t , file , pipe )
385
- })
386
- t .Run ("sync" , func (t * testing.T ) {
387
- t .Parallel ()
388
- name , pipe := newPipe (t , false , false )
389
- file := newFile (t , name , false )
390
- testReadWrite (t , file , pipe )
391
- })
390
+ tests := []struct {
391
+ name string
392
+ overlappedRead bool
393
+ overlappedWrite bool
394
+ pollable bool
395
+ }{
396
+ {"overlapped" , true , true , true },
397
+ {"overlapped-nonpollable" , true , true , false },
398
+ {"overlapped-write" , false , true , true },
399
+ {"overlapped-read" , true , false , true },
400
+ {"sync" , false , false , false },
401
+ {"sync-pollable" , false , false , true },
402
+ }
403
+ for _ , tt := range tests {
404
+ t .Run (tt .name , func (t * testing.T ) {
405
+ t .Parallel ()
406
+ name := pipeName ()
407
+ pipe := newBytePipe (t , name , tt .overlappedWrite , tt .pollable )
408
+ file := newFile (t , name , tt .overlappedRead , tt .pollable )
409
+ testReadWrite (t , pipe , file )
410
+ })
411
+ }
392
412
t .Run ("anonymous" , func (t * testing.T ) {
393
413
t .Parallel ()
394
414
var r , w syscall.Handle
@@ -404,16 +424,17 @@ func TestPipe(t *testing.T) {
404
424
}
405
425
}()
406
426
// CreatePipe always returns sync handles.
407
- fdr := newFD (t , r , "pipe" , false )
408
- fdw := newFD (t , w , "file" , false )
427
+ fdr := newFD (t , r , "pipe" , false , false )
428
+ fdw := newFD (t , w , "file" , false , false )
409
429
testReadWrite (t , fdr , fdw )
410
430
})
411
431
}
412
432
413
433
func TestPipeWriteEOF (t * testing.T ) {
414
434
t .Parallel ()
415
- name , pipe := newPipe (t , false , true )
416
- file := newFile (t , name , false )
435
+ name := pipeName ()
436
+ pipe := newMessagePipe (t , name , false , true )
437
+ file := newFile (t , name , false , true )
417
438
read := make (chan struct {}, 1 )
418
439
go func () {
419
440
_ , err := pipe .Write (nil )
@@ -435,8 +456,9 @@ func TestPipeWriteEOF(t *testing.T) {
435
456
436
457
func TestPipeCanceled (t * testing.T ) {
437
458
t .Parallel ()
438
- name , _ := newPipe (t , true , false )
439
- file := newFile (t , name , true )
459
+ name := pipeName ()
460
+ _ = newBytePipe (t , name , true , true )
461
+ file := newFile (t , name , true , true )
440
462
ch := make (chan struct {}, 1 )
441
463
go func () {
442
464
for {
@@ -481,7 +503,7 @@ func benchmarkRead(b *testing.B, overlapped bool) {
481
503
if err != nil {
482
504
b .Fatal (err )
483
505
}
484
- file := newFile (b , name , overlapped )
506
+ file := newFile (b , name , overlapped , true )
485
507
var buf [len (content )]byte
486
508
for b .Loop () {
487
509
_ , err := io .ReadFull (file , buf [:])
0 commit comments