@@ -328,6 +328,112 @@ func TestEpollConnectSameFD(t *testing.T) {
328328 Assert (t , n == 0 )
329329}
330330
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+ epevent := & epollevent {
349+ // netpollopen: runtime/netpoll_epoll.go
350+ events : syscall .EPOLLIN | syscall .EPOLLOUT | syscall .EPOLLRDHUP | EPOLLET ,
351+ data : [8 ]byte {},
352+ }
353+ err = EpollCtl (epollfd1 , syscall .EPOLL_CTL_ADD , epollfd2 , epevent )
354+ MustNil (t , err )
355+ n , err = epollWaitUntil (epollfd1 , events , 0 )
356+ Equal (t , n , 0 )
357+ MustNil (t , err )
358+
359+ // register rfd into epollfd2
360+ ioevent := & epollevent {
361+ events : syscall .EPOLLIN | syscall .EPOLLRDHUP | syscall .EPOLLERR ,
362+ data : [8 ]byte {},
363+ }
364+ err = EpollCtl (epollfd2 , syscall .EPOLL_CTL_ADD , rfd , ioevent )
365+ MustNil (t , err )
366+ n , err = epollWaitUntil (epollfd2 , events , 0 )
367+ Equal (t , n , 0 )
368+ MustNil (t , err )
369+
370+ // check epollfd2 readable
371+ n , err = syscall .Write (wfd , send )
372+ Equal (t , n , len (send ))
373+ MustNil (t , err )
374+ n , err = epollWaitUntil (epollfd1 , events , 0 )
375+ Equal (t , n , 1 )
376+ MustNil (t , err )
377+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
378+ n , err = epollWaitUntil (epollfd1 , events , 0 )
379+ Equal (t , n , 1 )
380+ MustNil (t , err )
381+
382+ // check rfd readable
383+ n , err = epollWaitUntil (epollfd2 , events , 0 )
384+ Equal (t , n , 1 )
385+ MustNil (t , err )
386+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
387+
388+ // read rfd
389+ n , err = syscall .Read (rfd , recv )
390+ Equal (t , n , len (send ))
391+ MustTrue (t , err == nil && string (recv ) == string (send ))
392+
393+ // check epollfd1 non-readable
394+ n , err = epollWaitUntil (epollfd1 , events , 0 )
395+ Equal (t , n , 0 )
396+ MustNil (t , err )
397+
398+ // check epollfd2 non-readable
399+ n , err = epollWaitUntil (epollfd2 , events , 0 )
400+ Equal (t , n , 0 )
401+ MustNil (t , err )
402+
403+ // close wfd
404+ err = syscall .Close (wfd )
405+ MustNil (t , err )
406+
407+ // check epollfd1 notified when peer closed
408+ n , err = epollWaitUntil (epollfd1 , events , 0 )
409+ Equal (t , n , 1 )
410+ MustNil (t , err )
411+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
412+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
413+
414+ // check epollfd2 notified when peer closed
415+ n , err = epollWaitUntil (epollfd2 , events , 0 )
416+ Equal (t , n , 1 )
417+ MustNil (t , err )
418+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
419+ Assert (t , events [0 ].events & syscall .EPOLLRDHUP != 0 )
420+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
421+
422+ // close rfd
423+ err = syscall .Close (rfd )
424+ MustNil (t , err )
425+
426+ // check epollfd1 non-readable
427+ n , err = epollWaitUntil (epollfd1 , events , 0 )
428+ Equal (t , n , 0 )
429+ MustNil (t , err )
430+
431+ // check epollfd2 non-readable
432+ n , err = epollWaitUntil (epollfd2 , events , 0 )
433+ Equal (t , n , 0 )
434+ MustNil (t , err )
435+ }
436+
331437func TestRuntimeNetpoller (t * testing.T ) {
332438 pfd , err := openPollFile ()
333439 MustNil (t , err )
0 commit comments