Exemple #1
0
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 );
}
Exemple #2
0
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 );
}
Exemple #3
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
}