/* performs all tasks defined for idle state */ void hb_idleState( void ) { PHB_IDLEDATA pIdleData = ( PHB_IDLEDATA ) hb_stackGetTSD( &s_idleData ); if( ! pIdleData->fIamIdle ) { pIdleData->fIamIdle = HB_TRUE; hb_releaseCPU(); if( hb_vmRequestQuery() == 0 ) { if( pIdleData->fCollectGarbage ) { hb_gcCollectAll( HB_FALSE ); pIdleData->fCollectGarbage = HB_FALSE; } if( pIdleData->pIdleTasks && pIdleData->iIdleTask < pIdleData->iIdleMaxTask ) { hb_itemRelease( hb_itemDo( pIdleData->pIdleTasks[ pIdleData->iIdleTask ], 0 ) ); ++pIdleData->iIdleTask; if( pIdleData->iIdleTask == pIdleData->iIdleMaxTask && hb_setGetIdleRepeat() ) { pIdleData->iIdleTask = 0; /* restart processing of idle tasks */ pIdleData->fCollectGarbage = HB_TRUE; } } } pIdleData->fIamIdle = HB_FALSE; } }
static SSL * s_SSL_itemGet( PHB_ITEM pItem, PHB_ITEM * pSSL, HB_BOOL * pfFree ) { SSL * ssl = NULL; if( pItem ) { PHB_ITEM pRelease = NULL; if( HB_IS_EVALITEM( pItem ) ) pItem = pRelease = hb_itemDo( pItem, 0 ); ssl = hb_SSL_itemGet( pItem ); if( ssl == NULL ) { SSL_CTX * ssl_ctx = hb_SSL_CTX_itemGet( pItem ); if( ssl_ctx ) { ssl = SSL_new( ssl_ctx ); if( pRelease ) hb_itemRelease( pRelease ); pItem = pRelease = NULL; } } if( ssl ) { * pSSL = pItem; * pfFree = pRelease != NULL; } else if( pRelease ) hb_itemRelease( pRelease ); } return ssl; }
/* RUN only one tasks, intentionally no check if bacground are active is done */ void hb_backgroundRunSingle( HB_ULONG ulID ) { PHB_BACKGROUNDTASK pBkgTask; if( ! s_bIamBackground ) { s_bIamBackground = HB_TRUE; pBkgTask = hb_backgroundFind( ulID ); if( pBkgTask ) hb_itemRelease( hb_itemDo( pBkgTask->pTask, 0 ) ); s_bIamBackground = HB_FALSE; } }
/* RUN all tasks defined in background state but only if SET BACKGROUND TASKS is ON*/ void hb_backgroundRun( void ) { HB_THREAD_STUB PHB_BACKGROUNDTASK pBkgTask; if( ! s_bIamBackground && hb_setGetBackgroundTasks() ) { s_bIamBackground = TRUE; if( s_uiBackgroundTask < s_uiBackgroundMaxTask ) { double dCurrSeconds = hb_seconds(); pBkgTask = ( PHB_BACKGROUNDTASK ) s_pBackgroundTasks[ s_uiBackgroundTask ]; /* check if hb_seconds() is lower than pBkgTask->dSeconds, if so midnight is reached */ if( ! ( pBkgTask->dSeconds ) || dCurrSeconds < pBkgTask->dSeconds ) pBkgTask->dSeconds = dCurrSeconds; /* Check if a task can run */ if( pBkgTask->bActive && ( pBkgTask->millisec == 0 || ( ( ( hb_seconds() - pBkgTask->dSeconds ) * 1000 ) >= pBkgTask->millisec ) ) ) { hb_itemRelease( hb_itemDo( pBkgTask->pTask, 0 ) ); pBkgTask->dSeconds = hb_seconds(); } ++s_uiBackgroundTask; } else { if( s_uiBackgroundMaxTask && s_uiBackgroundTask == s_uiBackgroundMaxTask ) s_uiBackgroundTask = 0; } s_bIamBackground = FALSE; } }
//------------------------------- // Manager of signals for windows // static LONG s_signalHandler( int type, int sig, PEXCEPTION_RECORD exc ) { PHB_ITEM pFunction, pExecArray, pRet; ULONG ulPos; UINT uiSig, uiMask; int iRet; // 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 EXCEPTION_EXECUTE_HANDLER; } bSignalEnabled = FALSE; ulPos = hb_arrayLen( sp_hooks ); // subsig not necessary uiSig = (UINT) s_translateSignal( (UINT)type, (UINT)sig ); while( ulPos > 0 ) { pFunction = hb_arrayGetItemPtr( sp_hooks, ulPos ); uiMask = (UINT) hb_arrayGetNI( pFunction, 1 ); if ( (uiMask & uiSig) == 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_arraySetForward( pExecArray, 1, hb_arrayGetItemPtr( pFunction, 2 ) ); hb_arraySetNI( pExecArray, 2, uiSig ); /* the third parameter is an array: * 1: low-level signal * 2: low-level subsignal * 3: low-level system error * 4: address that rised the signal * 5: process id of the signal riser * 6: UID of the riser */ pRet = hb_arrayGetItemPtr( pExecArray, 3); hb_arrayNew( pRet, 6 ); hb_arraySetNI( pRet, HB_SERVICE_OSSIGNAL, type ); hb_arraySetNI( pRet, HB_SERVICE_OSSUBSIG, sig ); //could be meaningless, but does not matter here hb_arraySetNI( pRet, HB_SERVICE_OSERROR, GetLastError() ); if (type == 0 ) //exception { hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, ( void * ) exc->ExceptionAddress ); } else { hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, NULL ); } //TODO: hb_arraySetNI( pRet, HB_SERVICE_PROCESS, GetCurrentThreadId() ); //TODO: hb_arraySetNI( pRet, HB_SERVICE_UID, 0 ); 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 EXCEPTION_CONTINUE_EXECUTION; case HB_SERVICE_QUIT: bSignalEnabled = FALSE; HB_CRITICAL_UNLOCK( s_ServiceMutex ); hb_vmRequestQuit(); #ifndef HB_THREAD_SUPPORT hb_vmQuit(); exit(0); #else hb_threadCancelInternal(); #endif } } ulPos--; } bSignalEnabled = TRUE; return EXCEPTION_EXECUTE_HANDLER; }
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 LRESULT CALLBACK hb_gt_wvw_EBProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { HWND hWndParent = GetParent( hWnd ); int nWin; int nCtrlId; WNDPROC OldProc; int nEBType; int iKey; PWVW_GLO wvw = hb_gt_wvw(); PWVW_WIN wvw_win; if( wvw == NULL || hWndParent == NULL ) return DefWindowProc( hWnd, message, wParam, lParam ); for( nWin = 0; nWin < wvw->iNumWindows; nWin++ ) { if( wvw->pWin[ nWin ]->hWnd == hWndParent ) break; } if( nWin >= wvw->iNumWindows ) return DefWindowProc( hWnd, message, wParam, lParam ); wvw_win = wvw->pWin[ nWin ]; nCtrlId = hb_gt_wvw_FindControlId( wvw_win, WVW_CONTROL_EDITBOX, hWnd, &nEBType ); if( nCtrlId == 0 ) { hb_errInternal( 10010, "EditBox: Control ID not found with hb_gt_wvw_FindControlId()", NULL, NULL ); return DefWindowProc( hWnd, message, wParam, lParam ); } OldProc = hb_gt_wvw_GetControlProc( wvw_win, WVW_CONTROL_EDITBOX, hWnd ); if( OldProc == NULL ) { hb_errInternal( 10011, "EditBox: Failed hb_gt_wvw_GetControlProc()", NULL, NULL ); return DefWindowProc( hWnd, message, wParam, lParam ); } iKey = 0; switch( message ) { case WM_KEYDOWN: case WM_SYSKEYDOWN: { HB_BOOL bAlt = GetKeyState( VK_MENU ) & 0x8000; int c = ( int ) wParam; switch( c ) { case VK_F1: iKey = hb_gt_wvw_JustTranslateKey( K_F1, K_SH_F1, K_ALT_F1, K_CTRL_F1 ); break; case VK_F2: iKey = hb_gt_wvw_JustTranslateKey( K_F2, K_SH_F2, K_ALT_F2, K_CTRL_F2 ); break; case VK_F3: iKey = hb_gt_wvw_JustTranslateKey( K_F3, K_SH_F3, K_ALT_F3, K_CTRL_F3 ); break; case VK_F4: if( bAlt ) { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } else iKey = hb_gt_wvw_JustTranslateKey( K_F4, K_SH_F4, K_ALT_F4, K_CTRL_F4 ); break; case VK_F5: iKey = hb_gt_wvw_JustTranslateKey( K_F5, K_SH_F5, K_ALT_F5, K_CTRL_F5 ); break; case VK_F6: iKey = hb_gt_wvw_JustTranslateKey( K_F6, K_SH_F6, K_ALT_F6, K_CTRL_F6 ); break; case VK_F7: iKey = hb_gt_wvw_JustTranslateKey( K_F7, K_SH_F7, K_ALT_F7, K_CTRL_F7 ); break; case VK_F8: iKey = hb_gt_wvw_JustTranslateKey( K_F8, K_SH_F8, K_ALT_F8, K_CTRL_F8 ); break; case VK_F9: iKey = hb_gt_wvw_JustTranslateKey( K_F9, K_SH_F9, K_ALT_F9, K_CTRL_F9 ); break; case VK_F10: iKey = hb_gt_wvw_JustTranslateKey( K_F10, K_SH_F10, K_ALT_F10, K_CTRL_F10 ); break; case VK_F11: iKey = hb_gt_wvw_JustTranslateKey( K_F11, K_SH_F11, K_ALT_F11, K_CTRL_F11 ); break; case VK_F12: iKey = hb_gt_wvw_JustTranslateKey( K_F12, K_SH_F12, K_ALT_F12, K_CTRL_F12 ); break; } break; } case WM_CHAR: { HB_BOOL bCtrl = GetKeyState( VK_CONTROL ) & 0x8000; int iScanCode = HB_LOBYTE( HIWORD( lParam ) ); int c = ( int ) wParam; if( bCtrl && iScanCode == 28 ) iKey = K_CTRL_RETURN; else if( bCtrl && ( c >= 1 && c <= 26 ) ) iKey = s_K_Ctrl[ c - 1 ]; else { switch( c ) { case VK_BACK: iKey = hb_gt_wvw_JustTranslateKey( K_BS, K_SH_BS, K_ALT_BS, K_CTRL_BS ); break; case VK_TAB: iKey = hb_gt_wvw_JustTranslateKey( K_TAB, K_SH_TAB, K_ALT_TAB, K_CTRL_TAB ); break; case VK_RETURN: iKey = hb_gt_wvw_JustTranslateKey( K_RETURN, K_SH_RETURN, K_ALT_RETURN, K_CTRL_RETURN ); break; case VK_ESCAPE: iKey = K_ESC; break; default: #if ! defined( UNICODE ) if( wvw_win->CodePage == OEM_CHARSET ) c = hb_gt_wvw_key_ansi_to_oem( c ); #endif iKey = c; } } break; } case WM_SYSCHAR: { int c, iScanCode = HB_LOBYTE( HIWORD( lParam ) ); switch( iScanCode ) { case 2: c = K_ALT_1; break; case 3: c = K_ALT_2; break; case 4: c = K_ALT_3; break; case 5: c = K_ALT_4; break; case 6: c = K_ALT_5; break; case 7: c = K_ALT_6; break; case 8: c = K_ALT_7; break; case 9: c = K_ALT_8; break; case 10: c = K_ALT_9; break; case 11: c = K_ALT_0; break; case 13: c = K_ALT_EQUALS; break; case 14: c = K_ALT_BS; break; case 16: c = K_ALT_Q; break; case 17: c = K_ALT_W; break; case 18: c = K_ALT_E; break; case 19: c = K_ALT_R; break; case 20: c = K_ALT_T; break; case 21: c = K_ALT_Y; break; case 22: c = K_ALT_U; break; case 23: c = K_ALT_I; break; case 24: c = K_ALT_O; break; case 25: c = K_ALT_P; break; case 30: c = K_ALT_A; break; case 31: c = K_ALT_S; break; case 32: c = K_ALT_D; break; case 33: c = K_ALT_F; break; case 34: c = K_ALT_G; break; case 35: c = K_ALT_H; break; case 36: c = K_ALT_J; break; case 37: c = K_ALT_K; break; case 38: c = K_ALT_L; break; case 44: c = K_ALT_Z; break; case 45: c = K_ALT_X; break; case 46: c = K_ALT_C; break; case 47: c = K_ALT_V; break; case 48: c = K_ALT_B; break; case 49: c = K_ALT_N; break; case 50: c = K_ALT_M; break; default: c = ( int ) wParam; } iKey = c; break; } } if( iKey != 0 ) { HB_BOOL fCodeExec = HB_FALSE; PHB_ITEM pKey = hb_itemPutNI( NULL, iKey ); PHB_ITEM pCodeblock = hb_itemDoC( "SETKEY", 1, pKey ); if( HB_IS_EVALITEM( pCodeblock ) ) { PHB_ITEM pReturn; SetFocus( hWndParent ); pReturn = hb_itemDo( pCodeblock, 0 ); hb_itemRelease( pReturn ); SetFocus( hWnd ); fCodeExec = HB_TRUE; } hb_itemRelease( pCodeblock ); hb_itemRelease( pKey ); if( fCodeExec ) return 0; } switch( message ) { case WM_KEYDOWN: case WM_SYSKEYDOWN: { HB_BOOL bAlt = GetKeyState( VK_MENU ) & 0x8000; HB_BOOL bCtrl = GetKeyState( VK_CONTROL ) & 0x8000; HB_BOOL bShift = GetKeyState( VK_SHIFT ) & 0x8000; int c = ( int ) wParam; HB_BOOL fMultiline; if( ! hb_gt_wvw_BufferedKey( ( int ) wParam ) ) break; fMultiline = ( ( nEBType & WVW_EB_MULTILINE ) == WVW_EB_MULTILINE ); switch( c ) { case VK_F4: if( bAlt ) { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } break; case VK_RETURN: if( fMultiline || bAlt || bShift || bCtrl ) break; else if( ! fMultiline ) { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } case VK_ESCAPE: if( bAlt || bShift || bCtrl ) break; else { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } case VK_UP: case VK_DOWN: case VK_PRIOR: case VK_NEXT: if( fMultiline ) break; else { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } case VK_TAB: if( ! bCtrl && ! bAlt ) { SetFocus( hWndParent ); PostMessage( hWndParent, message, wParam, lParam ); return 0; } break; case VK_BACK: if( ! bAlt ) break; if( SendMessage( hWnd, EM_CANUNDO, 0, 0 ) ) { SendMessage( hWnd, EM_UNDO, 0, 0 ); return 0; } break; } break; } case WM_CHAR: { HB_BOOL bCtrl = GetKeyState( VK_CONTROL ) & 0x8000; switch( ( int ) wParam ) { case VK_TAB: return 0; case 1: if( bCtrl ) { SendMessage( hWnd, EM_SETSEL, 0, ( LPARAM ) -1 ); return 0; } break; } break; } } return CallWindowProc( OldProc, hWnd, message, wParam, lParam ); }
PHB_ITEM hb_errLaunchSubst( PHB_ITEM pError ) { PHB_ITEM pResult; HB_TRACE( HB_TR_DEBUG, ( "hb_errLaunchSubst(%p)", pError ) ); if( pError ) { PHB_ERRDATA pErrData = ( PHB_ERRDATA ) hb_stackGetTSD( &s_errData ); HB_USHORT uiFlags = hb_errGetFlags( pError ); /* Check if we have a valid error handler */ if( ! pErrData->errorBlock || ! HB_IS_EVALITEM( pErrData->errorBlock ) ) hb_errInternal( HB_EI_ERRNOBLOCK, NULL, NULL, NULL ); /* Check if the error launcher was called too many times recursively */ if( pErrData->iLaunchCount == HB_ERROR_LAUNCH_MAX ) hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL ); /* Launch the error handler: "xResult := Eval( ErrorBlock(), oError )" */ pErrData->iLaunchCount++; /* set DosError() to last OS error code */ pErrData->uiErrorDOS = ( int ) hb_errGetOsCode( pError ); /* Add one try to the counter. */ if( uiFlags & EF_CANRETRY ) hb_errPutTries( pError, ( HB_USHORT ) ( hb_errGetTries( pError ) + 1 ) ); if( pErrData->errorHandler ) { /* there is a low-level error handler defined - use it instead * of normal Harbour level one */ pErrData->errorHandler->Error = pError; pErrData->errorHandler->ErrorBlock = pErrData->errorBlock; pResult = ( pErrData->errorHandler->Func )( pErrData->errorHandler ); pErrData->errorHandler->Error = NULL; } else pResult = hb_itemDo( pErrData->errorBlock, 1, pError ); pErrData->iLaunchCount--; /* Check results */ if( hb_vmRequestQuery() != 0 ) { if( pResult ) hb_itemRelease( pResult ); pResult = NULL; } else { /* If the canSubstitute flag has not been set, consider it as a failure. */ if( ! ( uiFlags & EF_CANSUBSTITUTE ) ) hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } } else pResult = hb_itemNew( NULL ); return pResult; }
HB_USHORT hb_errLaunch( PHB_ITEM pError ) { HB_USHORT uiAction = E_DEFAULT; /* Needed to avoid GCC -O2 warning */ HB_TRACE( HB_TR_DEBUG, ( "hb_errLaunch(%p)", pError ) ); if( pError ) { PHB_ERRDATA pErrData = ( PHB_ERRDATA ) hb_stackGetTSD( &s_errData ); HB_USHORT uiFlags = hb_errGetFlags( pError ); PHB_ITEM pResult; /* Check if we have a valid error handler */ if( ! pErrData->errorBlock || ! HB_IS_EVALITEM( pErrData->errorBlock ) ) hb_errInternal( HB_EI_ERRNOBLOCK, NULL, NULL, NULL ); /* Check if the error launcher was called too many times recursively */ if( pErrData->iLaunchCount == HB_ERROR_LAUNCH_MAX ) hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL ); /* Launch the error handler: "lResult := Eval( ErrorBlock(), oError )" */ pErrData->iLaunchCount++; /* set DosError() to last OS error code */ pErrData->uiErrorDOS = ( int ) hb_errGetOsCode( pError ); /* Add one try to the counter. */ if( uiFlags & EF_CANRETRY ) hb_errPutTries( pError, ( HB_USHORT ) ( hb_errGetTries( pError ) + 1 ) ); if( pErrData->errorHandler ) { /* there is a low-level error handler defined - use it instead * of normal Harbour level one */ pErrData->errorHandler->Error = pError; pErrData->errorHandler->ErrorBlock = pErrData->errorBlock; pResult = ( pErrData->errorHandler->Func )( pErrData->errorHandler ); pErrData->errorHandler->Error = NULL; } else pResult = hb_itemDo( pErrData->errorBlock, 1, pError ); pErrData->iLaunchCount--; /* Check results */ if( hb_vmRequestQuery() != 0 ) { if( pResult ) hb_itemRelease( pResult ); uiAction = E_BREAK; } else if( pResult ) { HB_BOOL bFailure = HB_FALSE; /* If the error block didn't return a logical value, */ /* or the canSubstitute flag has been set, consider it as a failure */ if( ! HB_IS_LOGICAL( pResult ) || ( uiFlags & EF_CANSUBSTITUTE ) ) bFailure = HB_TRUE; else { uiAction = hb_itemGetL( pResult ) ? E_RETRY : E_DEFAULT; if( ( uiAction == E_DEFAULT && !( uiFlags & EF_CANDEFAULT ) ) || ( uiAction == E_RETRY && !( uiFlags & EF_CANRETRY ) ) ) bFailure = HB_TRUE; } hb_itemRelease( pResult ); if( bFailure ) hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } else hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } else uiAction = E_RETRY; /* Clipper does this, undocumented */ return uiAction; }
static int hb_matherrblock( HB_MATH_EXCEPTION * pexc ) { PHB_MATHERRDATA pMathErr = hb_mathErrData(); int retval; /* call codeblock for both case: handled and unhandled exceptions */ if( pMathErr->block ) { PHB_ITEM pArray, pRet; PHB_ITEM pType, pFuncname, pError, pArg1, pArg2, pRetval, pHandled; const char * funcname = pexc->funcname; if( funcname == HB_ERR_FUNCNAME ) { PHB_SYMB pSym = hb_itemGetSymbol( hb_stackBaseItem() ); if( pSym ) funcname = pSym->szName; } pType = hb_itemPutNI( NULL, pexc->type ); pFuncname = hb_itemPutC( NULL, funcname ); pError = hb_itemPutC( NULL, pexc->error ); pArg1 = hb_itemPutND( NULL, pexc->arg1 ); pArg2 = hb_itemPutND( NULL, pexc->arg2 ); pRetval = hb_itemPutNDLen( NULL, pexc->retval, pexc->retvalwidth, pexc->retvaldec ); pHandled = hb_itemPutL( NULL, pexc->handled ); pArray = hb_itemArrayNew( 2 ); hb_itemArrayPut( pArray, 1, pRetval ); hb_itemArrayPut( pArray, 2, pHandled ); /* launch error codeblock that can a) change the members of the array = {dRetval, lHandled} to set the return value of the math C RTL routine and the <exception handled flag> and it b) can return an integer value to set the return value of matherr(). NOTE that these values are only used if lHandled was .F. and is set to .T. within the codeblock */ pRet = hb_itemDo( pMathErr->block, 6, pType, pFuncname, pError, pArg1, pArg2, pArray ); hb_itemRelease( pType ); hb_itemRelease( pFuncname ); hb_itemRelease( pError ); hb_itemRelease( pArg1 ); hb_itemRelease( pArg2 ); hb_itemRelease( pRetval ); hb_itemRelease( pHandled ); if( pexc->handled ) { /* math exception has already been handled, so codeblock call above was only informative */ retval = 1; } else { /* exception handled by codeblock ? */ pHandled = hb_itemArrayGet( pArray, 2 ); if( pHandled ) { pexc->handled = hb_itemGetL( pHandled ); hb_itemRelease( pHandled ); } if( pexc->handled ) { /* YES ! */ /* extract retval for math routine and matherr() */ pRetval = hb_itemArrayGet( pArray, 1 ); if( pRetval ) { pexc->retval = hb_itemGetND( pRetval ); hb_itemGetNLen( pRetval, &pexc->retvalwidth, &pexc->retvaldec ); hb_itemRelease( pRetval ); } if( pRet && HB_IS_NUMERIC( pRet ) ) { retval = hb_itemGetNI( pRet ); /* block may also return 0 to force C math lib warnings */ hb_itemRelease( pRet ); } else { retval = 1; /* default return value to suppress C math lib warnings */ } } else { /* NO ! */ retval = 1; } } hb_itemRelease( pArray ); } else { retval = 1; /* default return value to suppress C math lib warnings */ } if( pMathErr->prevHandler ) { if( pexc->handled ) { /* the error is handled, so simply inform the previous handler */ ( *pMathErr->prevHandler )( pexc ); } else { /* else go on error handling within previous handler */ retval = ( *pMathErr->prevHandler )( pexc ); } } return retval; }
/* Manager of signals for windows */ static LONG s_signalHandler( int type, int sig, PEXCEPTION_RECORD exc ) { HB_SIZE nPos; HB_UINT uiSig; /* 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 EXCEPTION_EXECUTE_HANDLER; } s_bSignalEnabled = HB_FALSE; nPos = hb_arrayLen( s_pHooks ); /* subsig not necessary */ uiSig = ( HB_UINT ) s_translateSignal( ( HB_UINT ) type, ( HB_UINT ) sig ); 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 ) == 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_arraySetForward( pExecArray, 1, hb_arrayGetItemPtr( pFunction, 2 ) ); hb_arraySetNI( pExecArray, 2, uiSig ); /* the third parameter is an array: * 1: low-level signal * 2: low-level subsignal * 3: low-level system error * 4: address that rose the signal * 5: process id of the signal riser * 6: UID of the riser */ pRet = hb_arrayGetItemPtr( pExecArray, 3 ); hb_arrayNew( pRet, 6 ); hb_arraySetNI( pRet, HB_SERVICE_OSSIGNAL, type ); hb_arraySetNI( pRet, HB_SERVICE_OSSUBSIG, sig ); /* could be meaningless, but does not matter here */ hb_arraySetNI( pRet, HB_SERVICE_OSERROR, GetLastError() ); if( type == 0 ) /* exception */ hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, ( void * ) exc->ExceptionAddress ); else hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, NULL ); /* TODO: */ hb_arraySetNI( pRet, HB_SERVICE_PROCESS, GetCurrentThreadId() ); /* TODO: */ hb_arraySetNI( pRet, HB_SERVICE_UID, 0 ); 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 EXCEPTION_CONTINUE_EXECUTION; case HB_SERVICE_QUIT: s_bSignalEnabled = HB_FALSE; hb_threadLeaveCriticalSection( &s_ServiceMutex ); hb_vmRequestQuit(); #ifndef HB_THREAD_SUPPORT hb_vmQuit(); exit( 0 ); #else hb_threadCancelInternal(); #endif } } nPos--; } s_bSignalEnabled = HB_TRUE; return EXCEPTION_EXECUTE_HANDLER; }
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 }