static void s_signalHandlersInit() { #if defined( HB_THREAD_SUPPORT ) && ( defined( HB_OS_UNIX ) || defined( HB_OS_UNIX ) ) pthread_t res; HB_STACK * pStack; s_serviceSetHBSig(); pStack = hb_threadCreateStack( 0 ); pthread_create( &res, NULL, s_signalListener, pStack ); #else s_serviceSetHBSig(); #endif s_pHooks = hb_itemArrayNew( 0 ); hb_vmAtQuit( hb_service_exit, NULL ); }
static void s_signalHandlersInit() { #if defined( HB_THREAD_SUPPORT ) && ( defined( HB_OS_UNIX ) || defined( HB_OS_UNIX_COMPATIBLE ) ) pthread_t res; HB_STACK *pStack; s_serviceSetHBSig(); pStack = hb_threadCreateStack( 0 ); pthread_create( &res, NULL, s_signalListener, pStack ); #else s_serviceSetHBSig(); #endif #if defined( HB_THREAD_SUPPORT ) HB_CRITICAL_INIT( s_ServiceMutex ); #endif sp_hooks = hb_itemNew( NULL ); hb_arrayNew( sp_hooks, 0 ); }
static void s_signalHandler( int sig, siginfo_t * info, void * v ) #endif { HB_UINT uiSig; HB_SIZE nPos; #if ! ( defined( HB_OS_OS2_GCC ) || defined( __WATCOMC__ ) ) HB_SYMBOL_UNUSED( v ); #endif /* let's find the right signal handler. */ hb_threadEnterCriticalSectionGC( &s_ServiceMutex ); /* avoid working if PRG signal handling has been disabled */ if( ! s_bSignalEnabled ) { hb_threadLeaveCriticalSection( &s_ServiceMutex ); return; } s_bSignalEnabled = HB_FALSE; nPos = hb_arrayLen( s_pHooks ); /* subsig not necessary */ uiSig = ( HB_UINT ) s_translateSignal( ( HB_UINT ) sig, 0 ); while( nPos > 0 ) { PHB_ITEM pFunction; HB_UINT uiMask; pFunction = hb_arrayGetItemPtr( s_pHooks, nPos ); uiMask = ( HB_UINT ) hb_arrayGetNI( pFunction, 1 ); if( uiMask & uiSig ) { PHB_ITEM pExecArray, pRet; int iRet; /* we don't unlock the mutex now, even if it is a little dangerous. But we are in a signal hander... for now just 2 parameters */ pExecArray = hb_itemArrayNew( 3 ); hb_arraySet( pExecArray, 1, hb_arrayGetItemPtr( pFunction, 2 ) ); hb_arraySetNI( pExecArray, 2, uiSig ); /* the third parameter is an array: */ pRet = hb_arrayGetItemPtr( pExecArray, 3 ); #if defined( HB_OS_OS2_GCC ) || defined( __WATCOMC__ ) hb_arrayNew( pRet, 1 ); #elif defined( HB_OS_BSD ) hb_arrayNew( pRet, info ? 6 : 1 ); #else hb_arrayNew( pRet, 6 ); #endif hb_arraySetNI( pRet, HB_SERVICE_OSSIGNAL, sig ); #if ! ( defined( HB_OS_OS2_GCC ) || defined( __WATCOMC__ ) ) #if defined( HB_OS_BSD ) if( info ) #endif { hb_arraySetNI( pRet, HB_SERVICE_OSSUBSIG, info->si_code ); #if ! defined( HB_OS_VXWORKS ) hb_arraySetNI( pRet, HB_SERVICE_OSERROR, info->si_errno ); hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, ( void * ) info->si_addr ); hb_arraySetNI( pRet, HB_SERVICE_PROCESS, info->si_pid ); hb_arraySetNI( pRet, HB_SERVICE_UID, info->si_uid ); #endif } #endif pRet = hb_itemDo( pExecArray, 0 ); iRet = hb_itemGetNI( pRet ); hb_itemRelease( pRet ); hb_itemRelease( pExecArray ); switch( iRet ) { case HB_SERVICE_HANDLED: s_bSignalEnabled = HB_TRUE; hb_threadLeaveCriticalSection( &s_ServiceMutex ); return; case HB_SERVICE_QUIT: s_bSignalEnabled = HB_FALSE; hb_threadLeaveCriticalSection( &s_ServiceMutex ); /* TODO: A service cleanup routine */ hb_vmRequestQuit(); /* Allow signals to go through pthreads */ s_serviceSetDflSig(); /* NOTICE: should be pthread_exit(0), but a bug in Linux threading prevents it: calling pthread exit from a signal handler will cause infinite wait for restart signal. This solution is rude, while the other would allow clean VM termination... but it works. */ exit( 0 ); } } nPos--; } s_bSignalEnabled = HB_TRUE; #if 0 s_serviceSetHBSig(); #endif #if 0 if( uiSig != HB_SIGNAL_UNKNOWN ) { if( s_aOldAction[ sig ].sa_flags & SA_SIGINFO ) s_aOldAction[ sig ].sa_sigaction( sig, info, v ); else s_aOldAction[ sig ].sa_handler( sig ); } #endif }