// Set the label text void ModalProgressDialog::setTextAndFraction(const std::string& text, double fraction) { // If the aborted flag is set, throw an exception here if (_aborted) { throw OperationAbortedException(_("Operation cancelled by user")); } // Set the text _label->set_markup(text); if (fraction < 0) { fraction = 0.0; } else if (fraction > 1.0) { fraction = 1.0; } // Pulse the progress bar _progressBar->set_fraction(fraction); // Handle GTK events to make changes visible handleEvents(); }
void ModalProgressDialog::setText(const std::string& text) { // If the aborted flag is set, throw an exception here if (WasCancelled()) { throw OperationAbortedException(_("Operation cancelled by user")); } Pulse(text); }
size_t HandleStream::write(const void *buffer, size_t length) { if (m_cancelWrite) MORDOR_THROW_EXCEPTION(OperationAbortedException()); SchedulerSwitcher switcher(m_ioManager ? NULL : m_scheduler); DWORD written; OVERLAPPED *overlapped = NULL; if (m_ioManager) { MORDOR_ASSERT(Scheduler::getThis()); m_ioManager->registerEvent(&m_writeEvent); overlapped = &m_writeEvent.overlapped; if (supportsSeek()) { overlapped->Offset = (DWORD)m_pos; overlapped->OffsetHigh = (DWORD)(m_pos >> 32); } } length = (std::min)(length, m_maxOpSize); BOOL ret = WriteFile(m_hFile, buffer, (DWORD)length, &written, overlapped); Log::Level level = Log::DEBUG; if (!ret) { if (m_ioManager && GetLastError() == ERROR_IO_PENDING) level = Log::TRACE; else level = Log::ERROR; } DWORD error = GetLastError(); MORDOR_LOG_LEVEL(g_log, level) << this << " WriteFile(" << m_hFile << ", " << length << "): " << ret << " - " << written << " (" << error << ")"; if (m_ioManager) { if (!ret && error != ERROR_IO_PENDING) { m_ioManager->unregisterEvent(&m_writeEvent); MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("WriteFile"); } if (m_skipCompletionPortOnSuccess && ret) m_ioManager->unregisterEvent(&m_writeEvent); else Scheduler::yieldTo(); DWORD error = pRtlNtStatusToDosError((NTSTATUS)m_writeEvent.overlapped.Internal); MORDOR_LOG_LEVEL(g_log, error ? Log::ERROR : Log::VERBOSE) << this << " WriteFile(" << m_hFile << ", " << length << "): " << m_writeEvent.overlapped.InternalHigh << " (" << error << ")"; if (error) MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "WriteFile"); if (supportsSeek()) { m_pos = ((long long)overlapped->Offset | ((long long)overlapped->OffsetHigh << 32)) + m_writeEvent.overlapped.InternalHigh; } return m_writeEvent.overlapped.InternalHigh; } if (!ret) MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "WriteFile"); return written; }
// Set the label text void ModalProgressDialog::setTextAndFraction(const std::string& text, double fraction) { // If the aborted flag is set, throw an exception here if (_aborted) { throw OperationAbortedException("Operation cancelled by user"); } // Set the text gtk_label_set_markup(GTK_LABEL(_label), text.c_str()); // Pulse the progress bar gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_progressBar), fraction); // Handle GTK events to make changes visible handleEvents(); }
// Set the label text void ModalProgressDialog::setText(const std::string& text) { // If the aborted flag is set, throw an exception here if (_aborted) { throw OperationAbortedException(_("Operation cancelled by user")); } // Set the text _label->set_markup(text); // Pulse the progress bar _progressBar->pulse(); // Handle GTK events to make changes visible handleEvents(); }
void ModalProgressDialog::setTextAndFraction(const std::string& text, double fraction) { if (WasCancelled()) { throw OperationAbortedException(_("Operation cancelled by user")); } if (fraction < 0) { fraction = 0.0; } else if (fraction > 1.0) { fraction = 1.0; } int newValue = static_cast<int>(fraction * 100); Update(newValue, text); }
void Scheduler::run() { t_scheduler = this; if (gettid() != m_rootThread) { // Running in own thread t_fiber = Fiber::getThis().get(); } else { // Hijacked a thread MORDOR_ASSERT(t_fiber.get() == Fiber::getThis().get()); } Fiber::ptr idleFiber(new Fiber(boost::bind(&Scheduler::idle, this))); MORDOR_LOG_VERBOSE(g_log) << this << " starting thread with idle fiber " << idleFiber; Fiber::ptr dgFiber; // use a vector for O(1) .size() std::vector<FiberAndThread> batch(m_batchSize); bool isActive = false; while (true) { batch.clear(); bool dontIdle = false; bool tickleMe = false; { boost::mutex::scoped_lock lock(m_mutex); // Kill ourselves off if needed if (m_threads.size() > m_threadCount && gettid() != m_rootThread) { // Accounting if (isActive) --m_activeThreadCount; // Kill off the idle fiber try { throw boost::enable_current_exception( OperationAbortedException()); } catch(...) { idleFiber->inject(boost::current_exception()); } // Detach our thread for (std::vector<boost::shared_ptr<Thread> > ::iterator it = m_threads.begin(); it != m_threads.end(); ++it) if ((*it)->tid() == gettid()) { m_threads.erase(it); if (m_threads.size() > m_threadCount) tickle(); return; } MORDOR_NOTREACHED(); } std::list<FiberAndThread>::iterator it(m_fibers.begin()); while (it != m_fibers.end()) { // If we've met our batch size, and we're not checking to see // if we need to tickle another thread, then break if ( (tickleMe || m_activeThreadCount == threadCount()) && batch.size() == m_batchSize) break; if (it->thread != emptytid() && it->thread != gettid()) { MORDOR_LOG_DEBUG(g_log) << this << " skipping item scheduled for thread " << it->thread; // Wake up another thread to hopefully service this tickleMe = true; dontIdle = true; ++it; continue; } MORDOR_ASSERT(it->fiber || it->dg); // This fiber is still executing; probably just some race // race condition that it needs to yield on one thread // before running on another thread if (it->fiber && it->fiber->state() == Fiber::EXEC) { MORDOR_LOG_DEBUG(g_log) << this << " skipping executing fiber " << it->fiber; ++it; dontIdle = true; continue; } // We were just checking if there is more work; there is, so // set the flag and don't actually take this piece of work if (batch.size() == m_batchSize) { tickleMe = true; break; } batch.push_back(*it); it = m_fibers.erase(it); if (!isActive) { ++m_activeThreadCount; isActive = true; } } if (batch.empty() && isActive) { --m_activeThreadCount; isActive = false; } } if (tickleMe) tickle(); MORDOR_LOG_DEBUG(g_log) << this << " got " << batch.size() << " fiber/dgs to process (max: " << m_batchSize << ", active: " << isActive << ")"; MORDOR_ASSERT(isActive == !batch.empty()); if (!batch.empty()) { std::vector<FiberAndThread>::iterator it; for (it = batch.begin(); it != batch.end(); ++it) { Fiber::ptr f = it->fiber; boost::function<void ()> dg = it->dg; try { if (f && f->state() != Fiber::TERM) { MORDOR_LOG_DEBUG(g_log) << this << " running " << f; f->yieldTo(); } else if (dg) { if (!dgFiber) dgFiber.reset(new Fiber(dg)); dgFiber->reset(dg); MORDOR_LOG_DEBUG(g_log) << this << " running " << dg; dgFiber->yieldTo(); if (dgFiber->state() != Fiber::TERM) dgFiber.reset(); else dgFiber->reset(NULL); } } catch (...) { MORDOR_LOG_FATAL(Log::root()) << boost::current_exception_diagnostic_information(); throw; } } continue; } if (dontIdle) continue; if (idleFiber->state() == Fiber::TERM) { MORDOR_LOG_DEBUG(g_log) << this << " idle fiber terminated"; if (gettid() == m_rootThread) m_callingFiber.reset(); // Unblock the next thread if (threadCount() > 1) tickle(); return; } MORDOR_LOG_DEBUG(g_log) << this << " idling"; idleFiber->call(); } }