// 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);
}
Esempio n. 3
0
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);
}
Esempio n. 7
0
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();
    }
}