#include #include #include #include #include #include void handler( int omit ) { } int my_sleep( int long ms ) { int err = 0; struct timeval tv; tv.tv_sec = ms / 1000; tv.tv_usec = ( ms % 1000 ) * 1000; err = select( 0, NULL, NULL, NULL, &tv ); return ( ( err == -1 ) && ( errno == EINTR ) ? -1 : 0 ); } void* thr( void* err ) { timer_t timerid; struct sigevent sev; struct itimerspec its; sigset_t mask; int* perr = ( int* )err; *perr = 0; do { if ( sigemptyset( &mask ) != 0 ) { *perr = -1; break; } if ( sigaddset( &mask, SIGALRM ) != 0 ) { *perr = -1; break; } if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) != 0 ) { *perr = -1; break; } sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if ( timer_create(CLOCK_REALTIME, &sev, &timerid) != 0 ) { *perr = -1; break; } memset( &its, 0, sizeof ( its ) ); its.it_value.tv_nsec = 500 * 1000 * 1000; if ( timer_settime(timerid, 0, &its, NULL) != 0 ) { *perr = -1; break; } *perr = ( my_sleep( 2000 ) == -1 ? 0 : 1 ); } while ( 0 ); return ( NULL ); } int main( int argc, char *argv[] ) { sigset_t mask; struct sigaction sa; pthread_t t; int err = 0; sa.sa_flags = 0; sa.sa_handler = &handler; do { if ( sigemptyset( &mask ) != 0 ) { err = -1; break; } if ( sigaddset( &mask, SIGALRM ) != 0 ) { err = -1; break; } if ( sigprocmask( SIG_BLOCK, &mask, NULL ) != 0 ) { err = -1; break; } if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) != 0 ) { err = -1; break; } if ( sigemptyset( &sa.sa_mask ) != 0 ) { err = -1; break; } if ( sigaddset( &sa.sa_mask, SIGALRM ) != 0 ) { err = -1; break; } if ( sigaction( SIGALRM, &sa, NULL ) != 0 ) { err = -1; break; } if ( pthread_create( &t, NULL, &thr, &err ) != 0 ) { err = -1; break; } if ( pthread_join( t, NULL ) != 0 ) { err = -1; break; } } while ( 0 ); return ( err ); }