// returns FALSE if the mprotect call fails with an ENOMEM. // Raises assertions on other types of POSIX errors (since those typically reflect invalid object // or memory states). static bool _memprotect( void* baseaddr, size_t size, const PageProtectionMode& mode ) { PageSizeAssertionTest(size); uint lnxmode = 0; if (mode.CanWrite()) lnxmode |= PROT_WRITE; if (mode.CanRead()) lnxmode |= PROT_READ; if (mode.CanExecute()) lnxmode |= PROT_EXEC | PROT_READ; const int result = mprotect( baseaddr, size, lnxmode ); if (result == 0) return true; switch(errno) { case EINVAL: pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)", baseaddr, (uptr)baseaddr+size, mode.ToString().c_str()) ); break; case EACCES: pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X (mode=%s)", baseaddr, (uptr)baseaddr+size, mode.ToString().c_str()) ); break; case ENOMEM: // caller handles assertion or exception, or whatever. break; } return false; }
// Translates an Errno code into an exception. // Throws an exception based on the given error code (usually taken from ANSI C's errno) BaseException* Exception::FromErrno( const wxString& streamname, int errcode ) { pxAssumeDev( errcode != 0, "Invalid NULL error code? (errno)" ); switch( errcode ) { case EINVAL: pxFailDev( L"Invalid argument" ); return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)" ); case EACCES: // Access denied! return new Exception::AccessDenied( streamname ); case EMFILE: // Too many open files! return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"Too many open files"); // File handle allocation failure case EEXIST: return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"File already exists"); case ENOENT: // File not found! return new Exception::FileNotFound( streamname ); case EPIPE: return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Broken pipe"); case EBADF: return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Bad file number"); default: return &(new Exception::BadStream( streamname ))->SetDiagMsg(pxsFmt( L"General file/stream error [errno: %d]", errcode )); } }
int AppOpenModalDialog( wxString panel_name, wxWindow* parent=NULL ) { if( wxWindow* window = wxFindWindowByName( L"Dialog:" + DialogType::GetNameStatic() ) ) { window->SetFocus(); if( wxDialog* dialog = wxDynamicCast( window, wxDialog ) ) { // Switch to the requested panel. wxCommandEvent evt(pxEvt_SetSettingsPage); evt.SetString(panel_name); dialog->GetEventHandler()->ProcessEvent(evt); // It's legal to call ShowModal on a non-modal dialog, therefore making // it modal in nature for the needs of whatever other thread of action wants // to block against it: if( !dialog->IsModal() ) { int result = dialog->ShowModal(); dialog->Destroy(); return result; } } pxFailDev( "Can only show wxDialog class windows as modal!" ); return wxID_CANCEL; } else return DialogType( parent ).ShowModal(); }
// ---------------------------------------------------------------------------- // void pxLogConsole::DoLogRecord(wxLogLevel level, const wxString &message, const wxLogRecordInfo &info) { switch ( level ) { case wxLOG_Trace: case wxLOG_Debug: { wxString str; TimeStamp( &str ); MSW_OutputDebugString( str + message + L"\n" ); } break; case wxLOG_FatalError: // This one is unused by wx, and unused by PCSX2 (we prefer exceptions, thanks). pxFailDev( "Stop using FatalError and use assertions or exceptions instead." ); break; case wxLOG_Status: // Also unsed by wx, and unused by PCSX2 also (we prefer direct API calls to our main window!) pxFailDev( "Stop using wxLogStatus just access the Pcsx2App functions directly instead." ); break; case wxLOG_Info: if ( !GetVerbose() ) return; // fallthrough! case wxLOG_Message: Console.WriteLn( L"[wx] %s", WX_STR(message)); break; case wxLOG_Error: Console.Error(L"[wx] %s", WX_STR(message)); break; case wxLOG_Warning: Console.Warning(L"[wx] %s", WX_STR(message)); break; } }
// Returns the multitap slot number, range 1 to 3 (slot 0 refers to the standard // 1st and 2nd player slots). uint FileMcd_GetMtapSlot(uint slot) { switch( slot ) { case 0: case 1: pxFailDev( "Invalid parameter in call to GetMtapSlot -- specified slot is one of the base slots, not a Multitap slot." ); break; case 2: case 3: case 4: return slot-1; case 5: case 6: case 7: return slot-4; jNO_DEFAULT } return 0; // technically unreachable. }
int AppOpenModalDialog( wxWindow* parent=NULL ) { if( wxWindow* window = wxFindWindowByName( L"Dialog:" + DialogType::GetNameStatic() ) ) { window->SetFocus(); if( wxDialog* dialog = wxDynamicCast( window, wxDialog ) ) { // It's legal to call ShowModal on a non-modal dialog, therefore making // it modal in nature for the needs of whatever other thread of action wants // to block against it: if( !dialog->IsModal() ) { int result = dialog->ShowModal(); dialog->Destroy(); return result; } } pxFailDev( "Can only show wxDialog class windows as modal!" ); return wxID_CANCEL; } else return DialogType( parent ).ShowModal(); }
// ---------------------------------------------------------------------------- // Pass an uninitialized file object. The function will ask the user for the // filename and try to open it. It returns true on success (file was opened), // false if file couldn't be opened/created and -1 if the file selection // dialog was canceled. // static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent) { filename = wxSaveFileSelector(L"log", L"txt", L"log.txt", parent); if ( !filename ) return false; // canceled if( wxFile::Exists(filename) ) { bool bAppend = false; wxString strMsg; strMsg.Printf(L"Append log to file '%s' (choosing [No] will overwrite it)?", filename.c_str()); switch ( Msgbox::ShowModal( _("Save log question"), strMsg, MsgButtons().YesNo().Cancel() ) ) { case wxID_YES: bAppend = true; break; case wxID_NO: bAppend = false; break; case wxID_CANCEL: return false; default: pxFailDev( "invalid message box return value" ); } return ( bAppend ) ? file.Open(filename, wxFile::write_append) : file.Create(filename, true /* overwrite */); } return file.Create(filename); }
// Tests for Pause and Suspend/Close requests. If the thread is trying to be paused or // closed, it will enter a wait/holding pattern here in this method until the managing // thread releases it. Use the return value to detect if changes to the thread's state // may have been changed (based on the rule that other threads are not allowed to modify // this thread's state without pausing or closing it first, to prevent race conditions). // // Return value: // TRUE if the thread was paused or closed; FALSE if the thread // continued execution unimpeded. bool SysThreadBase::StateCheckInThread() { switch( m_ExecMode ) { #ifdef PCSX2_DEVBUILD // optimize out handlers for these cases in release builds. case ExecMode_NoThreadYet: // threads should never have this state set while the thread is in any way // active or alive. (for obvious reasons!!) pxFailDev( "Invalid execution state detected." ); return false; #endif case ExecMode_Opened: // Other cases don't need TestCancel() because its built into the various // threading wait/signal actions. TestCancel(); return false; // ------------------------------------- case ExecMode_Pausing: { OnPauseInThread(); m_ExecMode = ExecMode_Paused; m_RunningLock.Release(); } // fallthrough... case ExecMode_Paused: while( m_ExecMode == ExecMode_Paused ) m_sem_Resume.WaitWithoutYield(); m_RunningLock.Acquire(); if( m_ExecMode != ExecMode_Closing ) { OnResumeInThread( false ); break; } m_sem_ChangingExecMode.Post(); // fallthrough if we're switching to closing state... // ------------------------------------- case ExecMode_Closing: { OnSuspendInThread(); m_ExecMode = ExecMode_Closed; m_RunningLock.Release(); } // fallthrough... case ExecMode_Closed: while( m_ExecMode == ExecMode_Closed ) m_sem_Resume.WaitWithoutYield(); m_RunningLock.Acquire(); OnResumeInThread( true ); break; jNO_DEFAULT; } return true; }
uint xIndirectVoid::GetOperandSize() const { pxFailDev( "Invalid operation on xIndirectVoid" ); return 0; }
void pxLogConsole::DoLog( wxLogLevel level, const wxChar *szString, time_t t ) { wxString message(szString); #else void pxLogConsole::DoLogRecord(wxLogLevel level, const wxString &message, const wxLogRecordInfo &info) { #endif switch ( level ) { case wxLOG_Trace: case wxLOG_Debug: { wxString str; TimeStamp( &str ); MSW_OutputDebugString( str + message + L"\n" ); } break; case wxLOG_FatalError: // This one is unused by wx, and unused by PCSX2 (we prefer exceptions, thanks). pxFailDev( "Stop using FatalError and use assertions or exceptions instead." ); break; case wxLOG_Status: // Also unsed by wx, and unused by PCSX2 also (we prefer direct API calls to our main window!) pxFailDev( "Stop using wxLogStatus just access the Pcsx2App functions directly instead." ); break; case wxLOG_Info: if ( !GetVerbose() ) return; // fallthrough! case wxLOG_Message: Console.WriteLn( L"[wx] %s", WX_STR(message)); break; case wxLOG_Error: Console.Error(L"[wx] %s", WX_STR(message)); break; case wxLOG_Warning: Console.Warning(L"[wx] %s", WX_STR(message)); break; } } // ---------------------------------------------------------------------------- void ConsoleTestThread::ExecuteTaskInThread() { static int numtrack = 0; while( !m_done ) { // Two lines, both formatted, and varied colors. This makes for a fairly realistic // worst case scenario (without being entirely unrealistic). Console.WriteLn( L"This is a threaded logging test. Something bad could happen... %d", ++numtrack ); Console.Warning( L"Testing high stress loads %s", L"(multi-color)" ); Yield( 0 ); } } // ---------------------------------------------------------------------------- // Pass an uninitialized file object. The function will ask the user for the // filename and try to open it. It returns true on success (file was opened), // false if file couldn't be opened/created and -1 if the file selection // dialog was canceled. // static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent) { filename = wxSaveFileSelector(L"log", L"txt", L"log.txt", parent); if ( !filename ) return false; // canceled if( wxFile::Exists(filename) ) { bool bAppend = false; wxString strMsg; strMsg.Printf(L"Append log to file '%s' (choosing [No] will overwrite it)?", filename.c_str()); switch ( Msgbox::ShowModal( _("Save log question"), strMsg, MsgButtons().YesNo().Cancel() ) ) { case wxID_YES: bAppend = true; break; case wxID_NO: bAppend = false; break; case wxID_CANCEL: return false; default: pxFailDev( "invalid message box return value" ); } return ( bAppend ) ? file.Open(filename, wxFile::write_append) : file.Create(filename, true /* overwrite */); } return file.Create(filename); }