void hb_serviceExit() { if( sp_hooks != NULL ) { /* reset default signal handling */ s_serviceSetDflSig(); hb_itemRelease( sp_hooks ); } }
static void s_signalHandler( int sig, siginfo_t *info, void *v ) #endif { UINT uiMask; UINT uiSig; PHB_ITEM pFunction, pExecArray, pRet; ULONG ulPos; int iRet; #if !( defined( HB_OS_OS2_GCC ) || defined( __WATCOMC__ ) ) HB_SYMBOL_UNUSED(v); #endif // let's find the right signal handler. HB_CRITICAL_LOCK( s_ServiceMutex ); // avoid working if PRG signal handling has been disabled if ( ! bSignalEnabled ) { HB_CRITICAL_UNLOCK( s_ServiceMutex ); return; } bSignalEnabled = FALSE; ulPos = hb_arrayLen( sp_hooks ); // subsig not necessary uiSig = (UINT) s_translateSignal( (UINT)sig, 0 ); while( ulPos > 0 ) { pFunction = hb_arrayGetItemPtr( sp_hooks, ulPos ); uiMask = (UINT) hb_arrayGetNI( pFunction, 1 ); if ( uiMask & uiSig) { // 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 ); 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 pRet = hb_itemDo( pExecArray, 0 ); iRet = hb_itemGetNI( pRet ); hb_itemRelease( pRet ); hb_itemRelease( pExecArray ); switch( iRet ) { case HB_SERVICE_HANDLED: bSignalEnabled = TRUE; HB_CRITICAL_UNLOCK( s_ServiceMutex ); return; case HB_SERVICE_QUIT: bSignalEnabled = FALSE; HB_CRITICAL_UNLOCK( s_ServiceMutex ); //TODO: A service cleanup routine hb_vmRequestQuit(); #ifndef HB_THREAD_SUPPORT hb_vmQuit(); exit(0); #else /* Allow signals to go through pthreads */ s_serviceSetDflSig(); /* NOTICE: should be pthread_exit(0), but a bug in linuxthread 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); #endif } } ulPos--; } bSignalEnabled = TRUE; /*s_serviceSetHBSig();*/ /* TODO if ( uiSig != HB_SIGNAL_UNKNOWN ) { if ( sa_oldAction[ sig ].sa_flags & SA_SIGINFO ) { sa_oldAction[ sig ].sa_sigaction( sig, info, v ); } else { sa_oldAction[ sig ].sa_handler( sig ); } }*/ }
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 }