@ -1,5 +1,6 @@
// test_uasync_socket_race.c — тест гонки fd-reuse в epoll при быстром accept/close/accept
// test_uasync_socket_race.c — тест гонки fd-reuse в epoll при быстром accept/close/accept
// 4 дочерних процесса, каждый 200 connect+send+close. Сервер на uasync+tcp_io.
// 4 дочерних процесса, каждый 200 connect+send+close. Сервер на uasync+tcp_io.
// Проверяет что нет use-after-free при двойном epoll-событии (ERROR→free tc, WRITE→stale).
# include <stdio.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdlib.h>
# include <string.h>
# include <string.h>
@ -104,9 +105,11 @@ static void test_timeout(void* arg) {
int main ( void ) {
int main ( void ) {
printf ( " === test_uasync_socket_race === \n " ) ; fflush ( stdout ) ;
printf ( " === test_uasync_socket_race === \n " ) ; fflush ( stdout ) ;
debug_config_init ( ) ; debug_set_level ( DEBUG_LEVEL_ERROR ) ;
debug_config_init ( ) ;
for ( int i = 1 ; i < DEBUG_CATEGORY_COUNT ; i + + ) debug_set_category_level ( i , DEBUG_LEVEL_ERROR ) ;
srand ( ( unsigned ) getpid ( ) ) ;
srand ( ( unsigned ) getpid ( ) ) ;
close ( 0 ) ; open ( " /dev/null " , O_RDONLY ) ;
close ( 0 ) ; open ( " /dev/null " , O_RDONLY ) ; // резервируем fd 0
g_port = 25000 + ( rand ( ) % 10000 ) ;
g_port = 25000 + ( rand ( ) % 10000 ) ;
g_ua = uasync_create ( ) ;
g_ua = uasync_create ( ) ;
@ -122,7 +125,6 @@ int main(void) {
if ( bind ( lsock , ( struct sockaddr * ) & la , sizeof ( la ) ) < 0 ) { printf ( " [FAIL] bind: %s \n " , strerror ( errno ) ) ; goto cleanup ; }
if ( bind ( lsock , ( struct sockaddr * ) & la , sizeof ( la ) ) < 0 ) { printf ( " [FAIL] bind: %s \n " , strerror ( errno ) ) ; goto cleanup ; }
if ( listen ( lsock , 32 ) < 0 ) { printf ( " [FAIL] listen: %s \n " , strerror ( errno ) ) ; goto cleanup ; }
if ( listen ( lsock , 32 ) < 0 ) { printf ( " [FAIL] listen: %s \n " , strerror ( errno ) ) ; goto cleanup ; }
uasync_add_socket ( g_ua , lsock , on_accept_cb , NULL , NULL , NULL ) ;
uasync_add_socket ( g_ua , lsock , on_accept_cb , NULL , NULL , NULL ) ;
printf ( " listen fd=%d epoll ok \n " , lsock ) ; fflush ( stdout ) ;
for ( int i = 0 ; i < CHILDREN ; i + + ) {
for ( int i = 0 ; i < CHILDREN ; i + + ) {
pid_t pid = fork ( ) ;
pid_t pid = fork ( ) ;