// Called on the worker thread. nsresult BackgroundFileSaver::ProcessAttention() { nsresult rv; // This function is called whenever the attention of the worker thread has // been requested. This may happen in these cases: // * We are about to start the copy for the first time. In this case, we are // called from an event posted on the worker thread from the control thread // by GetWorkerThreadAttention, and mAsyncCopyContext is null. // * We have interrupted the copy for some reason. In this case, we are // called by AsyncCopyCallback, and mAsyncCopyContext is null. // * We are currently executing ProcessStateChange, and attention is requested // by the control thread, for example because SetTarget or Finish have been // called. In this case, we are called from from an event posted through // GetWorkerThreadAttention. While mAsyncCopyContext was always null when // the event was posted, at this point mAsyncCopyContext may not be null // anymore, because ProcessStateChange may have started the copy before the // event that called this function was processed on the worker thread. // If mAsyncCopyContext is not null, we interrupt the copy and re-enter // through AsyncCopyCallback. This allows us to check if, for instance, we // should rename the target file. We will then restart the copy if needed. if (mAsyncCopyContext) { NS_CancelAsyncCopy(mAsyncCopyContext, NS_ERROR_ABORT); return NS_OK; } // Use the current shared state to determine the next operation to execute. rv = ProcessStateChange(); if (NS_FAILED(rv)) { // If something failed while processing, terminate the operation now. { MutexAutoLock lock(mLock); if (NS_SUCCEEDED(mStatus)) { mStatus = rv; } } // Ensure we notify completion now that the operation failed. CheckCompletion(); } return NS_OK; }
//------------------------------------------------------------------------------ Solver::SolverState Solver::AdvanceState() { switch (currentState) { case INITIALIZING: CompleteInitialization(); break; case NOMINAL: RunNominal(); break; case PERTURBING: RunPerturbation(); break; case ITERATING: RunIteration(); break; case CALCULATING: CalculateParameters(); break; case CHECKINGRUN: CheckCompletion(); break; case RUNEXTERNAL: RunExternal(); break; case FINISHED: RunComplete(); break; default: throw SolverException(wxT("Undefined Solver state")); }; ReportProgress(); return currentState; }
//------------------------------------------------------------------------------ Solver::SolverState BatchEstimator::AdvanceState() { switch (currentState) { case INITIALIZING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "INITIALIZING\n"); #endif // ReportProgress(); CompleteInitialization(); break; case PROPAGATING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "PROPAGATING\n"); #endif // ReportProgress(); FindTimeStep(); break; case CALCULATING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "CALCULATING\n"); #endif // ReportProgress(); CalculateData(); break; case LOCATING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "LOCATING\n"); #endif // ReportProgress(); ProcessEvent(); break; case ACCUMULATING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "ACCUMULATING\n"); #endif // ReportProgress(); Accumulate(); break; case ESTIMATING: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "ESTIMATING\n"); #endif // ReportProgress(); Estimate(); break; case CHECKINGRUN: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "CHECKINGRUN\n"); #endif // ReportProgress(); CheckCompletion(); break; case FINISHED: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "FINISHED\n"); #endif RunComplete(); // ReportProgress(); break; default: #ifdef DEBUG_STATE_MACHINE MessageInterface::ShowMessage("Entered Estimator state machine: " "Bad state for an estimator.\n"); #endif /* throw EstimatorException("Solver state not supported for the simulator")*/; } return currentState; }
//------------------------------------------------------------------------------ Solver::SolverState SteepestDescent::AdvanceState() { switch (currentState) { case INITIALIZING: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("INITIALIZING\n")); #endif iterationsTaken = 0; WriteToTextFile(); // ReportProgress(); CompleteInitialization(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), INITIALIZING, currentState); #endif break; case NOMINAL: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("NOMINAL\n")); #endif // ReportProgress(); RunNominal(); // ReportProgress(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), NOMINAL, currentState); #endif // ReportProgress(); break; case PERTURBING: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("PERTURBING\n")); #endif RunPerturbation(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), PERTURBING, currentState); #endif // ReportProgress(); break; case Solver::CALCULATING: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("CALCULATING\n")); #endif // ReportProgress(); CalculateParameters(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), CALCULATING, currentState); #endif break; case CHECKINGRUN: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("CHECKINGRUN\n")); #endif CheckCompletion(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), CHECKINGRUN, currentState); #endif // ReportProgress(); break; case FINISHED: #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage(wxT("Entered state machine; ") wxT("FINISHED\n")); #endif RunComplete(); #ifdef SD_DEBUG_STATE_MACHINE MessageInterface::ShowMessage( wxT("SteepestDescent State Transitions from %d to %d\n"), FINISHED, currentState); #endif // ReportProgress(); break; default: throw SolverException( wxT("Steepest Descent Solver \"") + instanceName + wxT("\" encountered an unexpected state.")); } return currentState; }
// Called on the worker thread. nsresult BackgroundFileSaver::ProcessStateChange() { nsresult rv; // We might have been notified because the operation is complete, verify. if (CheckCompletion()) { return NS_OK; } // Get a copy of the current shared state for the worker thread. nsCOMPtr<nsIFile> initialTarget; bool initialTargetKeepPartial; nsCOMPtr<nsIFile> renamedTarget; bool renamedTargetKeepPartial; bool sha256Enabled; bool append; { MutexAutoLock lock(mLock); initialTarget = mInitialTarget; initialTargetKeepPartial = mInitialTargetKeepPartial; renamedTarget = mRenamedTarget; renamedTargetKeepPartial = mRenamedTargetKeepPartial; sha256Enabled = mSha256Enabled; append = mAppend; // From now on, another attention event needs to be posted if state changes. mWorkerThreadAttentionRequested = false; } // The initial target can only be null if it has never been assigned. In this // case, there is nothing to do since we never created any output file. if (!initialTarget) { return NS_OK; } // Determine if we are processing the attention request for the first time. bool isContinuation = !!mActualTarget; if (!isContinuation) { // Assign the target file for the first time. mActualTarget = initialTarget; mActualTargetKeepPartial = initialTargetKeepPartial; } // Verify whether we have actually been instructed to use a different file. // This may happen the first time this function is executed, if SetTarget was // called two times before the worker thread processed the attention request. bool equalToCurrent = false; if (renamedTarget) { rv = mActualTarget->Equals(renamedTarget, &equalToCurrent); NS_ENSURE_SUCCESS(rv, rv); if (!equalToCurrent) { // If we were asked to rename the file but the initial file did not exist, // we simply create the file in the renamed location. We avoid this check // if we have already started writing the output file ourselves. bool exists = true; if (!isContinuation) { rv = mActualTarget->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); } if (exists) { // We are moving the previous target file to a different location. nsCOMPtr<nsIFile> renamedTargetParentDir; rv = renamedTarget->GetParent(getter_AddRefs(renamedTargetParentDir)); NS_ENSURE_SUCCESS(rv, rv); nsAutoString renamedTargetName; rv = renamedTarget->GetLeafName(renamedTargetName); NS_ENSURE_SUCCESS(rv, rv); // We must delete any existing target file before moving the current // one. rv = renamedTarget->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); if (exists) { rv = renamedTarget->Remove(false); NS_ENSURE_SUCCESS(rv, rv); } // Move the file. If this fails, we still reference the original file // in mActualTarget, so that it is deleted if requested. If this // succeeds, the nsIFile instance referenced by mActualTarget mutates // and starts pointing to the new file, but we'll discard the reference. rv = mActualTarget->MoveTo(renamedTargetParentDir, renamedTargetName); NS_ENSURE_SUCCESS(rv, rv); } // Now we can update the actual target file name. mActualTarget = renamedTarget; mActualTargetKeepPartial = renamedTargetKeepPartial; } } // Notify if the target file name actually changed. if (!equalToCurrent) { // We must clone the nsIFile instance because mActualTarget is not // immutable, it may change if the target is renamed later. nsCOMPtr<nsIFile> actualTargetToNotify; rv = mActualTarget->Clone(getter_AddRefs(actualTargetToNotify)); NS_ENSURE_SUCCESS(rv, rv); RefPtr<NotifyTargetChangeRunnable> event = new NotifyTargetChangeRunnable(this, actualTargetToNotify); NS_ENSURE_TRUE(event, NS_ERROR_FAILURE); rv = mControlThread->Dispatch(event, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); } if (isContinuation) { // The pending rename operation might be the last task before finishing. We // may return here only if we have already created the target file. if (CheckCompletion()) { return NS_OK; } // Even if the operation did not complete, the pipe input stream may be // empty and may have been closed already. We detect this case using the // Available property, because it never returns an error if there is more // data to be consumed. If the pipe input stream is closed, we just exit // and wait for more calls like SetTarget or Finish to be invoked on the // control thread. However, we still truncate the file or create the // initial digest context if we are expected to do that. uint64_t available; rv = mPipeInputStream->Available(&available); if (NS_FAILED(rv)) { return NS_OK; } } // Create the digest context if requested and NSS hasn't been shut down. if (sha256Enabled && !mDigestContext) { nsNSSShutDownPreventionLock lock; if (!isAlreadyShutDown()) { mDigestContext = UniquePK11Context( PK11_CreateDigestContext(SEC_OID_SHA256)); NS_ENSURE_TRUE(mDigestContext, NS_ERROR_OUT_OF_MEMORY); } } // When we are requested to append to an existing file, we should read the // existing data and ensure we include it as part of the final hash. if (mDigestContext && append && !isContinuation) { nsCOMPtr<nsIInputStream> inputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), mActualTarget, PR_RDONLY | nsIFile::OS_READAHEAD); if (rv != NS_ERROR_FILE_NOT_FOUND) { NS_ENSURE_SUCCESS(rv, rv); char buffer[BUFFERED_IO_SIZE]; while (true) { uint32_t count; rv = inputStream->Read(buffer, BUFFERED_IO_SIZE, &count); NS_ENSURE_SUCCESS(rv, rv); if (count == 0) { // We reached the end of the file. break; } nsNSSShutDownPreventionLock lock; if (isAlreadyShutDown()) { return NS_ERROR_NOT_AVAILABLE; } nsresult rv = MapSECStatus(PK11_DigestOp(mDigestContext.get(), uint8_t_ptr_cast(buffer), count)); NS_ENSURE_SUCCESS(rv, rv); } rv = inputStream->Close(); NS_ENSURE_SUCCESS(rv, rv); } } // We will append to the initial target file only if it was requested by the // caller, but we'll always append on subsequent accesses to the target file. int32_t creationIoFlags; if (isContinuation) { creationIoFlags = PR_APPEND; } else { creationIoFlags = (append ? PR_APPEND : PR_TRUNCATE) | PR_CREATE_FILE; } // Create the target file, or append to it if we already started writing it. // The 0600 permissions are used while the file is being downloaded, and for // interrupted downloads. Those may be located in the system temporary // directory, as well as the target directory, and generally have a ".part" // extension. Those part files should never be group or world-writable even // if the umask allows it. nsCOMPtr<nsIOutputStream> outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mActualTarget, PR_WRONLY | creationIoFlags, 0600); NS_ENSURE_SUCCESS(rv, rv); outputStream = NS_BufferOutputStream(outputStream, BUFFERED_IO_SIZE); if (!outputStream) { return NS_ERROR_FAILURE; } // Wrap the output stream so that it feeds the digest context if needed. if (mDigestContext) { // No need to acquire the NSS lock here, DigestOutputStream must acquire it // in any case before each asynchronous write. Constructing the // DigestOutputStream cannot fail. Passing mDigestContext to // DigestOutputStream is safe, because BackgroundFileSaver always outlives // the outputStream. BackgroundFileSaver is reference-counted before the // call to AsyncCopy, and mDigestContext is never destroyed before // AsyncCopyCallback. outputStream = new DigestOutputStream(outputStream, mDigestContext.get()); } // Start copying our input to the target file. No errors can be raised past // this point if the copy starts, since they should be handled by the thread. { MutexAutoLock lock(mLock); rv = NS_AsyncCopy(mPipeInputStream, outputStream, mWorkerThread, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096, AsyncCopyCallback, this, false, true, getter_AddRefs(mAsyncCopyContext), GetProgressCallback()); if (NS_FAILED(rv)) { NS_WARNING("NS_AsyncCopy failed."); mAsyncCopyContext = nullptr; return rv; } } // If the operation succeeded, we must ensure that we keep this object alive // for the entire duration of the copy, since only the raw pointer will be // provided as the argument of the AsyncCopyCallback function. We can add the // reference now, after NS_AsyncCopy returned, because it always starts // processing asynchronously, and there is no risk that the callback is // invoked before we reach this point. If the operation failed instead, then // AsyncCopyCallback will never be called. NS_ADDREF_THIS(); return NS_OK; }
/** * The example to do the scatter gather transfer through polling. * * @param DeviceId is the Device Id of the XAxiCdma instance * * @return * - XST_SUCCESS if example finishes successfully * - XST_FAILURE if error occurs * * @note None * ******************************************************************************/ int XAxiCdma_SgPollExample(u16 DeviceId) { XAxiCdma_Config *CfgPtr; int Status; u8 *SrcPtr; u8 *DstPtr; SrcPtr = (u8 *)TransmitBufferPtr; DstPtr = (u8 *)ReceiveBufferPtr; #ifdef __aarch64__ Xil_SetTlbAttributes(BD_SPACE_BASE, MARK_UNCACHEABLE); #endif /* Initialize the XAxiCdma device. */ CfgPtr = XAxiCdma_LookupConfig(DeviceId); if (!CfgPtr) { xdbg_printf(XDBG_DEBUG_ERROR, "Cannot find config structure for device %d\r\n", XPAR_AXICDMA_0_DEVICE_ID); return XST_FAILURE; } Status = XAxiCdma_CfgInitialize(&AxiCdmaInstance, CfgPtr, CfgPtr->BaseAddress); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Initialization failed with %d\r\n", Status); return XST_FAILURE; } /* Setup the BD ring */ Status = SetupTransfer(&AxiCdmaInstance); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Setup BD ring failed with %d\r\n", Status); return XST_FAILURE; } Done = 0; Error = 0; /* Start the DMA transfer */ Status = DoTransfer(&AxiCdmaInstance); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Do transfer failed with %d\r\n", Status); return XST_FAILURE; } /* Wait until the DMA transfer is done or error occurs */ while ((CheckCompletion(&AxiCdmaInstance) < NUMBER_OF_BDS_TO_TRANSFER) && !Error) { /* Wait */ } if(Error) { int TimeOut = RESET_LOOP_COUNT; xdbg_printf(XDBG_DEBUG_ERROR, "Transfer has error %x\r\n", Error); /* Need to reset the hardware to restore to the correct state */ XAxiCdma_Reset(&AxiCdmaInstance); while (TimeOut) { if (XAxiCdma_ResetIsDone(&AxiCdmaInstance)) { break; } TimeOut -= 1; } /* Reset has failed, print a message to notify the user */ if (!TimeOut) { xdbg_printf(XDBG_DEBUG_ERROR, "Reset hardware failed with %d\r\n", Status); } return XST_FAILURE; } /* Transfer completed successfully, check data */ Status = CheckData(SrcPtr, DstPtr, MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER); if (Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for sg " "transfer\r\n"); return XST_FAILURE; } /* Test finishes successfully, return successfully */ return XST_SUCCESS; }
BOOL CWndGuideSystem::Process() { if( !(g_tmCurrent > m_dwTime+SEC(2.5)) ) return TRUE; if( m_pModel == NULL ) return FALSE; // 여기부턴 인포팡 모델 처리 m_pModel->FrameMove(); if( m_pModel->IsEndFrame() ) { if( m_bAniState == ANI_INTRO ) { if( g_pPlayer ) SetAni( g_pPlayer->GetJob(), ANI_IDLE ); } else if( m_bAniState == ANI_BYTE ) { m_bVisible = FALSE; m_bAniState = ANI_IDLE; } } // 여기부터 가이드 스크립트 처리 if(m_CurrentGuide.m_nVicCondition) { // 대상 가이드가 있으면 가이드의 완료 조건을 체크한다 if(CheckCompletion(m_CurrentGuide)) { if(m_CurrentIter == m_mapGuide.end()) { // 마지막가이드이면 종료처리한다 m_wndGuideText->SetVisible(FALSE); g_Option.m_nTutorialLv = m_CurrentGuide.m_nLevel; g_DPlay.SendTutorialState(g_Option.m_nTutorialLv); if(g_Option.m_nTutorialLv > 0) m_pWndTutorialView->AddToList(g_Option.m_nTutorialLv - 1); m_CurrentGuide.init(); m_CurrentIter = NULL; } else if(m_CurrentIter == NULL) { // 이벤트성(일회성) 이벤트일 경우는 다음이 없다 m_wndGuideText->SetVisible(FALSE); if(m_CurrentGuide.m_nLevel > g_Option.m_nTutorialLv) { g_Option.m_nTutorialLv = m_CurrentGuide.m_nLevel; //if(g_Option.m_nTutorialLv > 0) // m_pWndTutorialView->AddToList(g_Option.m_nTutorialLv - 1); } m_CurrentGuide.init(); } else { // 마지막이 아니면 다음 가이드로 ++m_CurrentIter; if(m_CurrentIter != m_mapGuide.end()) { m_CurrentGuide = m_CurrentIter->second; m_wndGuideText->AddGuideText(m_CurrentGuide); if(m_CurrentGuide.m_nLevel > g_Option.m_nTutorialLv + 1) { g_Option.m_nTutorialLv = m_CurrentGuide.m_nLevel - 1; g_DPlay.SendTutorialState(g_Option.m_nTutorialLv); if(g_Option.m_nTutorialLv > 0) m_pWndTutorialView->AddToList(g_Option.m_nTutorialLv - 1); } } else { m_wndGuideText->SetVisible(FALSE); g_Option.m_nTutorialLv = m_CurrentGuide.m_nLevel; g_DPlay.SendTutorialState(g_Option.m_nTutorialLv); if(g_Option.m_nTutorialLv > 0) m_pWndTutorialView->AddToList(g_Option.m_nTutorialLv - 1); m_CurrentIter = NULL; m_CurrentGuide.init(); } } } } m_Condition.Init(); return TRUE; }
//------------------------------------------------------------------------------ Solver::SolverState SequentialEstimator::AdvanceState() { switch (currentState) { case INITIALIZING: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the INITIALIZING state\n"); #endif CompleteInitialization(); break; case PROPAGATING: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the PROPAGATING state\n"); #endif FindTimeStep(); break; case CALCULATING: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the CALCULATING state\n"); #endif CalculateData(); break; case LOCATING: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the LOCATING state\n"); #endif ProcessEvent(); break; case ESTIMATING: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the ESTIMATING state\n"); #endif Estimate(); break; case CHECKINGRUN: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the CHECKINGRUN state\n"); #endif CheckCompletion(); break; case FINISHED: #ifdef WALK_STATE_MACHINE MessageInterface::ShowMessage("Executing the FINISHED state\n"); #endif RunComplete(); break; default: throw EstimatorException("Unknown state encountered in the " + instanceName + " sequential estimator."); } return currentState; }