@@ -328,6 +328,104 @@ func TestEpollConnectSameFD(t *testing.T) {
328
328
Assert (t , n == 0 )
329
329
}
330
330
331
+ func TestEpollWaitEpollFD (t * testing.T ) {
332
+ epollfd1 , err := EpollCreate (0 ) // monitor epollfd2
333
+ MustNil (t , err )
334
+ epollfd2 , err := EpollCreate (0 ) // monitor io fds
335
+ MustNil (t , err )
336
+ MustNil (t , err )
337
+ defer syscall .Close (epollfd1 )
338
+ defer syscall .Close (epollfd2 )
339
+
340
+ rfd , wfd := GetSysFdPairs ()
341
+ defer syscall .Close (wfd )
342
+ send := []byte ("hello" )
343
+ recv := make ([]byte , 5 )
344
+ events := make ([]epollevent , 128 )
345
+ n := 0
346
+
347
+ // register epollfd2 into epollfd1
348
+ event := & epollevent {
349
+ events : syscall .EPOLLIN | syscall .EPOLLRDHUP | syscall .EPOLLERR ,
350
+ data : [8 ]byte {},
351
+ }
352
+ err = EpollCtl (epollfd1 , syscall .EPOLL_CTL_ADD , epollfd2 , event )
353
+ MustNil (t , err )
354
+ n , err = epollWaitUntil (epollfd1 , events , 0 )
355
+ Equal (t , n , 0 )
356
+ MustNil (t , err )
357
+
358
+ // register rfd into epollfd2
359
+ err = EpollCtl (epollfd2 , syscall .EPOLL_CTL_ADD , rfd , event )
360
+ MustNil (t , err )
361
+ n , err = epollWaitUntil (epollfd2 , events , 0 )
362
+ Equal (t , n , 0 )
363
+ MustNil (t , err )
364
+
365
+ // check epollfd2 readable
366
+ n , err = syscall .Write (wfd , send )
367
+ Equal (t , n , len (send ))
368
+ MustNil (t , err )
369
+ n , err = epollWaitUntil (epollfd1 , events , 0 )
370
+ Equal (t , n , 1 )
371
+ MustNil (t , err )
372
+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
373
+
374
+ // check rfd readable
375
+ n , err = epollWaitUntil (epollfd2 , events , 0 )
376
+ Equal (t , n , 1 )
377
+ MustNil (t , err )
378
+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
379
+
380
+ // read rfd
381
+ n , err = syscall .Read (rfd , recv )
382
+ Equal (t , n , len (send ))
383
+ MustTrue (t , err == nil && string (recv ) == string (send ))
384
+
385
+ // check epollfd1 non-readable
386
+ n , err = epollWaitUntil (epollfd1 , events , 0 )
387
+ Equal (t , n , 0 )
388
+ MustNil (t , err )
389
+
390
+ // check epollfd2 non-readable
391
+ n , err = epollWaitUntil (epollfd2 , events , 0 )
392
+ Equal (t , n , 0 )
393
+ MustNil (t , err )
394
+
395
+ // close wfd
396
+ err = syscall .Close (wfd )
397
+ MustNil (t , err )
398
+
399
+ // check epollfd1 notified when peer closed
400
+ n , err = epollWaitUntil (epollfd1 , events , 0 )
401
+ Equal (t , n , 1 )
402
+ MustNil (t , err )
403
+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
404
+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
405
+
406
+ // check epollfd2 notified when peer closed
407
+ n , err = epollWaitUntil (epollfd2 , events , 0 )
408
+ Equal (t , n , 1 )
409
+ MustNil (t , err )
410
+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
411
+ Assert (t , events [0 ].events & syscall .EPOLLRDHUP != 0 )
412
+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
413
+
414
+ // close rfd
415
+ err = syscall .Close (rfd )
416
+ MustNil (t , err )
417
+
418
+ // check epollfd1 non-readable
419
+ n , err = epollWaitUntil (epollfd1 , events , 0 )
420
+ Equal (t , n , 0 )
421
+ MustNil (t , err )
422
+
423
+ // check epollfd2 non-readable
424
+ n , err = epollWaitUntil (epollfd2 , events , 0 )
425
+ Equal (t , n , 0 )
426
+ MustNil (t , err )
427
+ }
428
+
331
429
func TestRuntimeNetpoller (t * testing.T ) {
332
430
pfd , err := openPollFile ()
333
431
MustNil (t , err )
0 commit comments