Ejemplo n.º 1
0
void HouseKeeper::Start(void)
{
    // no need to be fine grained, nothing else should be accessing this map
    QMutexLocker mapLock(&m_mapLock);

    if (m_timer->isActive())
        // Start() should only be called once
        return;

    MSqlQuery query(MSqlQuery::InitCon());
    query.prepare("SELECT tag,lastrun"
                  "  FROM housekeeping"
                  " WHERE hostname = :HOST"
                  "    OR hostname IS NULL");
    query.bindValue(":HOST", gCoreContext->GetHostName());

    if (!query.exec())
        MythDB::DBError("HouseKeeper::Run", query);
    else
    {
        while (query.next())
        {
            // loop through housekeeping table and load last run timestamps
            QString tag = query.value(0).toString();
            QDateTime lastrun = MythDate::as_utc(query.value(1).toDateTime());

            if (m_taskMap.contains(tag))
                m_taskMap[tag]->SetLastRun(lastrun);
        }
    }

    gCoreContext->addListener(this);

    QMap<QString,HouseKeeperTask*>::const_iterator it;
    for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
    {
        if ((*it)->CheckImmediate())
        {
            // run any tasks marked for immediate operation in-thread
            (*it)->UpdateLastRun();
            (*it)->Run();
        }
        else if ((*it)->CheckStartup())
        {
            // queue any tasks marked for startup
            LOG(VB_GENERAL, LOG_INFO,
                QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
            QMutexLocker queueLock(&m_queueLock);
            (*it)->IncrRef();
            m_taskQueue.enqueue(*it);
        }
    }

    LOG(VB_GENERAL, LOG_INFO, "Starting HouseKeeper.");

    if (!m_taskQueue.isEmpty())
        StartThread();

    m_timer->start();
}
Ejemplo n.º 2
0
REFERENCE_TIME CWASAPIRenderFilter::BufferredDataDuration()
{
  REFERENCE_TIME rtDuration = 0;
  REFERENCE_TIME rtStart = 0;
  REFERENCE_TIME rtStop = 0;
  HRESULT hr = S_OK;

  {
    CAutoLock queueLock(&m_inputQueueLock);

    vector<TQueueEntry>::iterator it = m_inputQueue.begin();
    while (it != m_inputQueue.end())
    {
      // EOS marker is currently a NULL sample
      if (it->Sample)
      {
        if (SUCCEEDED(hr = it->Sample->GetTime(&rtStart, &rtStop)))
          rtDuration += rtStop - rtStart;
        else
          Log("CWASAPIRenderFilter::BufferredDataDuration Failed to get sample times");
      }
      ++it;
    }
  }

  CAutoLock lock(&m_csCurrentSample);

  if (m_pCurrentSample.p)
  {
    UINT nFrames = (m_pCurrentSample.p->GetActualDataLength() - m_nSampleOffset) / m_pInputFormat->Format.nBlockAlign;
    rtDuration += nFrames * UNITS / m_pInputFormat->Format.nSamplesPerSec;
  }

  return rtDuration;
}
Ejemplo n.º 3
0
void TaskDispatcher2::addTask(TaskJob &&task) {
	{
		std::lock_guard<std::mutex> queueLock(m_queueMutex);
		m_taskQueue.push(std::move(task));
	}
	m_condition.notify_all();
}
Ejemplo n.º 4
0
// Get the next sample in the queue. If there is none, wait for at most
// dwTimeout milliseconds for one to become available before failing.
// Returns: S_FALSE if no sample available
// Threading: only one thread should be calling GetNextSampleOrCommand()
// but it can be different from the one calling PutSample()/PutCommand()
HRESULT CQueuedAudioSink::GetNextSampleOrCommand(AudioSinkCommand* pCommand, IMediaSample** pSample, DWORD dwTimeout,
                                                  vector<HANDLE>* pHandles, vector<DWORD>* pWaitObjects, bool handleOOBOnly)
{
  HRESULT hr = WaitForEvents(dwTimeout, pHandles, pWaitObjects);

  if (hr == MPAR_S_WAIT_TIMED_OUT || hr == S_FALSE)
  {
    if (pSample && *pSample && !handleOOBOnly)
    {
      (*pSample)->Release();
      (*pSample) = NULL;
    }

    *pCommand = ASC_Nop;
    return WAIT_TIMEOUT;
  }
  
  {
    CAutoLock OOBQueueLock(&m_OOBInputQueueLock);
    if (!m_OOBInputQueue.empty())
    {
      TQueueEntry entry = m_OOBInputQueue.front();
      if (pCommand)
        *pCommand = entry.Command;
      
      m_OOBInputQueue.pop();

      if (m_OOBInputQueue.empty())
        ResetEvent(m_hOOBCommandAvailableEvent);

      return S_OK;
    }
    else if (handleOOBOnly)
    {
      *pCommand = ASC_Nop;
      return S_OK;
    }
  }

  if (hr != S_OK)
    return hr;

  if (pSample && *pSample)
    (*pSample)->Release();

  CAutoLock queueLock(&m_inputQueueLock);
  TQueueEntry entry = m_inputQueue.front();
  if (pSample)
    *pSample = entry.Sample.Detach();
  if (pCommand)
    *pCommand = entry.Command;

  m_inputQueue.erase(m_inputQueue.begin());
  if (m_inputQueue.empty())
    ResetEvent(m_hInputAvailableEvent);
  //if (m_InputQueue.empty())
  //  SetEvent(m_hInputQueueEmptyEvent);

  return S_OK;
}
Ejemplo n.º 5
0
HRESULT CQueuedAudioSink::PutOOBCommand(AudioSinkCommand nCommand)
{
  CAutoLock queueLock(&m_OOBInputQueueLock);
  m_OOBInputQueue.push(nCommand);
  SetEvent(m_hOOBCommandAvailableEvent);

  return S_OK;
}
Ejemplo n.º 6
0
void COverlayRenderer::FreeOverlayQueue(const uint8_t plane)
{
  CAutoLock queueLock(&m_csOverlayQueue);
  ivecOverlayQueue it = m_overlayQueue[plane].begin();
  while (it != m_overlayQueue[plane].end())
  {
    it = FreeOverlay(it);
  }
}
Ejemplo n.º 7
0
HRESULT CQueuedAudioSink::PutCommand(AudioSinkCommand nCommand)
{
  CAutoLock queueLock(&m_inputQueueLock);
  m_inputQueue.push_back(nCommand);
  SetEvent(m_hInputAvailableEvent);
  //if(m_hInputQueueEmptyEvent)
  //  ResetEvent(m_hInputQueueEmptyEvent);

  return S_OK;
}
Ejemplo n.º 8
0
HouseKeeper::~HouseKeeper(void)
{
    gCoreContext->removeListener(this);

    if (m_timer)
    {
        m_timer->stop();
        disconnect(m_timer);
        delete m_timer;
        m_timer = NULL;
    }

    {
        // remove anything from the queue first, so it does not start
        QMutexLocker queueLock(&m_queueLock);
        while (!m_taskQueue.isEmpty())
            m_taskQueue.takeFirst()->DecrRef();
    }

    {
        // issue a terminate call to any long-running tasks
        // this is just a noop unless overwritten by a subclass
        QMutexLocker mapLock(&m_mapLock);
        QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
        for (; it != m_taskMap.end(); ++it)
            (*it)->Terminate();
    }

    if (!m_threadList.isEmpty())
    {
        QMutexLocker threadLock(&m_threadLock);
        // tell primary thread to self-terminate and wake it
        m_threadList.first()->Discard();
        m_threadList.first()->Wake();
        // wait for any remaining threads to self-terminate and close
        while (!m_threadList.isEmpty())
        {
            HouseKeepingThread *thread = m_threadList.takeFirst();
            thread->wait();
            delete thread;
        }
    }

    {
        // unload any registered tasks
        QMutexLocker mapLock(&m_mapLock);
        QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
        while (it != m_taskMap.end())
        {
            (*it)->DecrRef();
            it = m_taskMap.erase(it);
        }
    }
}
Ejemplo n.º 9
0
TaskDispatcher2::~TaskDispatcher2() {
	{
		std::lock_guard<std::mutex> queueLock(m_queueMutex);
		m_stop = true;
	}
	m_condition.notify_all();
	for (size_t i{ 0 }; i < m_threadVector.size(); ++i) {
		if (m_threadVector[i].joinable()) {
			m_threadVector[i].join();
		}
	}
}
Ejemplo n.º 10
0
// Processing
HRESULT CQueuedAudioSink::PutSample(IMediaSample *pSample)
{
  if (m_bFlushing)
    return S_OK;

  CAutoLock queueLock(&m_inputQueueLock);
  m_inputQueue.push_back(pSample);
  SetEvent(m_hInputAvailableEvent);
  //if(m_hInputQueueEmptyEvent)
  //  ResetEvent(m_hInputQueueEmptyEvent);

  return S_OK;
}
Ejemplo n.º 11
0
void TaskDispatcher2::exec() {
	std::unique_lock<std::mutex> queueLock(m_queueMutex);
	do {
		m_condition.wait(queueLock, [this] { return !m_taskQueue.empty() || m_stop; });
		if (!m_taskQueue.empty()) {
			const auto task = std::move(m_taskQueue.front());
			m_taskQueue.pop();

			queueLock.unlock();
			task();
			queueLock.lock();
		}
	} while (!m_stop || !m_taskQueue.empty());
}
Ejemplo n.º 12
0
void Mailbox::push(std::unique_ptr<Message> message) {
    std::lock_guard<std::mutex> pushingLock(pushingMutex);

    if (closed) {
        return;
    }

    std::lock_guard<std::mutex> queueLock(queueMutex);
    bool wasEmpty = queue.empty();
    queue.push(std::move(message));
    if (wasEmpty) {
        scheduler.schedule(shared_from_this());
    }
}
Ejemplo n.º 13
0
void HouseKeeper::Run(void)
{
    LOG(VB_GENERAL, LOG_DEBUG, "Running HouseKeeper.");

    QDateTime now = MythDate::current();

    QMutexLocker mapLock(&m_mapLock);
    QMap<QString,HouseKeeperTask*>::const_iterator it;
    for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
    {
        if ((*it)->CheckRun(now))
        {
            // check if any tasks are ready to run, and add to queue
            LOG(VB_GENERAL, LOG_INFO,
                QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
            QMutexLocker queueLock(&m_queueLock);
            (*it)->IncrRef();
            m_taskQueue.enqueue(*it);
        }
    }

    if (!m_taskQueue.isEmpty())
        StartThread();

    if (m_threadList.size() > 1)
    {
        // spent threads exist in the thread list
        // check to see if any have finished up their task and terminated
        QMutexLocker threadLock(&m_threadLock);
        int count1 = m_threadList.size();

        QList<HouseKeepingThread*>::iterator it = m_threadList.begin();
        ++it; // skip the primary thread
        while (it != m_threadList.end())
        {
            if ((*it)->isRunning())
                ++it;
            else
                it = m_threadList.erase(it);
        }

        int count2 = m_threadList.size();
        if (count1 > count2)
            LOG(VB_GENERAL, LOG_DEBUG,
                QString("Discarded HouseKeepingThreads have completed and "
                        "been deleted. Current count %1 -> %2.")
                .arg(count1).arg(count2));
    }
}
Ejemplo n.º 14
0
HouseKeeperTask* HouseKeeper::GetQueuedTask(void)
{
    QMutexLocker queueLock(&m_queueLock);
    HouseKeeperTask *task = NULL;

    if (!m_taskQueue.isEmpty())
    {
        task = m_taskQueue.dequeue();
        task->IncrRef();
    }

    // returning NULL tells the thread that the queue is empty and
    // to go into standby
    return task;
}
Ejemplo n.º 15
0
    void ICharacter::consumeHP (const uint32_t amount)
    {
        if (amount)
        {
            boost::mutex::scoped_lock stats_lock(m_stats_mutex);

            if (m_HP)
            {
                if ( amount > m_HP)
                    m_HP = 0;
                else
                    m_HP -= amount;

                if (!m_HP)
                {
                    stats_lock.unlock();

                    if (!signal_dead.empty())
                        signal_dead(m_UniqueID,m_CurrentPos);

                    boost::lock(m_state_mutex,m_queue_mutex,m_mov_mutex);

                    boost::unique_lock<boost::mutex> stateLock(m_state_mutex,boost::adopt_lock);
                    boost::unique_lock<boost::mutex> queueLock(m_queue_mutex,boost::adopt_lock);
                    boost::unique_lock<boost::mutex> moveLock(m_mov_mutex,boost::adopt_lock);

                    if (m_AttackState != ATTACK_ACTION_STOP)
                    {
                        m_AttackState = ATTACK_ACTION_STOP;

                        if (!signal_state.empty())
                            signal_state(STATE_ATTACK,m_AttackState);
                    }

                    m_StatusState = STATUS_ACTION_DEAD;

                    if (!signal_state.empty())
                        signal_state(STATE_STATUS,m_StatusState);

                    m_QueueSkill = 0;
                    m_QueueTarget = 0;
                    m_CurrentTask = 0;

                    m_NextPos = Coord();
                }
            }
        }
    }
Ejemplo n.º 16
0
HRESULT CQueuedAudioSink::BeginFlush()
{
  ResetEvent(m_hCurrentSampleReleased);

  // Request the derived class to release the current sample and stall threadproc
  PutOOBCommand(ASC_Flush);

  {
    CAutoLock queueLock(&m_inputQueueLock);
    ResetEvent(m_hInputAvailableEvent);
    while (!m_inputQueue.empty())
      m_inputQueue.erase(m_inputQueue.begin());
    //SetEvent(m_hInputQueueEmptyEvent);
  }

  return CBaseAudioSink::BeginFlush();
}
Ejemplo n.º 17
0
    void retireTask(Task* task) {
        std::unique_lock<std::mutex> counterLock(m_threadCounterMutex);
        m_threadsDoneCount++;

        if (m_threadsDoneCount >= m_totalThreads) {
            task->notifyComplete();
            m_threadsDoneCount = 0;

            std::unique_lock<std::mutex> queueLock(m_queueMutex);
            m_tasks.pop();

            if (m_tasks.empty()) {
                m_tasksComplete.notify_all();
            }
        }

        counterLock.unlock();
        m_barrier.wait();
    }
Ejemplo n.º 18
0
void COverlayRenderer::ScheduleOverlays()
{
  CAutoLock queueLock(&m_csOverlayQueue);

  REFERENCE_TIME rtDue = 0;
  if (NextScheduleTime(rtDue, BD_OVERLAY_IG))
  {
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = -rtDue;

#ifdef LOG_DRAWING
    LogDebug("           liDueTime: %6.3f", liDueTime.QuadPart / 10000000.0);
#endif

    if (SetWaitableTimer(m_hOverlayTimerIG, &liDueTime, 0, NULL, NULL, 0) == 0)
    {
#ifdef LOG_DRAWING
      DWORD error = GetLastError();
      LogDebug("COverlayRenderer::ScheduleOverlay - SetWaitableTimer failed: %d", error);
#endif
    }
  }

  if (NextScheduleTime(rtDue, BD_OVERLAY_PG))
  {
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = -rtDue;

#ifdef LOG_DRAWING
    LogDebug("           liDueTime: %6.3f", liDueTime.QuadPart / 10000000.0);
#endif

    if (SetWaitableTimer(m_hOverlayTimerPG, &liDueTime, 0, NULL, NULL, 0) == 0)
    {
#ifdef LOG_DRAWING
      DWORD error = GetLastError();
      LogDebug("COverlayRenderer::ScheduleOverlay - SetWaitableTimer failed: %d", error);
#endif
    }
  }
}
Ejemplo n.º 19
0
void AsyncThreadManager::itemConsumer(WorkQueue& workQueue, condition_variable& workAvailable, recursive_mutex& queueMutex, bool &finished)
{
	while(true)
	{
		cz::unique_lock<cz::recursive_mutex> queueLock(queueMutex);
		while(!finished && workQueue.empty())
			workAvailable.wait(queueLock);

		if (finished)
			break;

		detail::AsyncWorkItemBase* workItem = workQueue.front();
		workQueue.pop();
		// unlock so other threads can remove work items while we compute this one
		queueLock.unlock();

		// Compute the result (this will put the value in the "future" object the user is holding)
		workItem->run();
		CZ_DELETE workItem;
	}
}
Ejemplo n.º 20
0
void COverlayRenderer::OverlayProc(const BD_OVERLAY* ov)
{
  if (!ov)
    return;
  
  if (ov->cmd == BD_OVERLAY_CLOSE || ov->cmd == BD_OVERLAY_INIT)
  {
    ProcessOverlay(ov);
    return;
  }

  BD_OVERLAY_EX *copy = (BD_OVERLAY_EX*)malloc(sizeof(BD_OVERLAY_EX));
  if (!copy)
    return;

  memcpy(copy, ov, sizeof(*ov));
  copy->scheduled = false;

  if (ov->palette) 
  {
    copy->palette = (BD_PG_PALETTE_ENTRY*)malloc(PALETTE_SIZE * sizeof(BD_PG_PALETTE_ENTRY));
    memcpy((void*)copy->palette, ov->palette, PALETTE_SIZE * sizeof(BD_PG_PALETTE_ENTRY));
  }

  if (copy->img)
    m_pLib->IncreaseRefCount(copy->img);

  {
#ifdef LOG_DRAWING
    LogDebug("new arriva PTS: %6.3f wait: %6.3f", (CONVERT_90KHz_DS(copy->pts)) / 10000000.0);
#endif

    CAutoLock queueLock(&m_csOverlayQueue);

    m_overlayQueue[copy->plane].push_back(copy);
    SetEvent(m_hNewOverlayAvailable);
  }
}
Ejemplo n.º 21
0
COverlayRenderer::~COverlayRenderer()
{
  CAutoLock renderLock(&m_csRenderLock);
  CAutoLock queueLock(&m_csOverlayQueue);

  FreeOverlayQueue(BD_OVERLAY_IG);
  FreeOverlayQueue(BD_OVERLAY_PG);

  if (m_hOverlayTimerIG)
  {
    CloseHandle(m_hOverlayTimerIG);
    m_hOverlayTimerIG = NULL;
  }

  if (m_hOverlayTimerPG)
  {
    CloseHandle(m_hOverlayTimerPG);
    m_hOverlayTimerPG = NULL;
  }

  if (m_hNewOverlayAvailable)
    CloseHandle(m_hNewOverlayAvailable);

  if (m_hStopThreadEvent)
  {
    SetEvent(m_hStopThreadEvent);
    CloseHandle(m_hStopThreadEvent);
    WaitForSingleObject(m_hThread, INFINITE);
  }

  if (m_hThread)
    CloseHandle(m_hThread);

  CloseOverlay(BD_OVERLAY_PG);
  CloseOverlay(BD_OVERLAY_IG);
}
Ejemplo n.º 22
0
void S3KeyWriter::flushBuffer() {
    if (!this->buffer.empty()) {
        UniqueLock queueLock(&this->mutex);
        while (this->activeThreads >= this->params.getNumOfChunks()) {
            pthread_cond_wait(&this->cv, &this->mutex);
        }

        // Most time query is canceled during uploadPartOfData(). This is the first chance to cancel
        // and clean up upload.
        this->checkQueryCancelSignal();

        this->activeThreads++;

        pthread_t writerThread;
        ThreadParams* params = new ThreadParams();
        params->keyWriter = this;
        params->data.swap(this->buffer);
        params->currentNumber = ++this->partNumber;
        pthread_create(&writerThread, NULL, UploadThreadFunc, params);
        threadList.emplace_back(writerThread);

        this->buffer.reserve(this->params.getChunkSize());
    }
}
Ejemplo n.º 23
0
void Mailbox::receive() {
    std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);

    if (closed) {
        return;
    }

    std::unique_ptr<Message> message;
    bool wasEmpty;

    {
        std::lock_guard<std::mutex> queueLock(queueMutex);
        assert(!queue.empty());
        message = std::move(queue.front());
        queue.pop();
        wasEmpty = queue.empty();
    }

    (*message)();

    if (!wasEmpty) {
        scheduler.schedule(shared_from_this());
    }
}
Ejemplo n.º 24
0
REFERENCE_TIME CWASAPIRenderFilter::BufferredDataDuration()
{
  CAutoLock queueLock(&m_inputQueueLock);

  REFERENCE_TIME rtDuration = 0;
  REFERENCE_TIME rtStart = 0;
  REFERENCE_TIME rtStop = 0;

  vector<TQueueEntry>::iterator it = m_inputQueue.begin();
  while (it != m_inputQueue.end())
  {
    it->Sample->GetTime(&rtStart, &rtStop);
    rtDuration += rtStop - rtStart;
    ++it;
  }

  if (m_pCurrentSample.p)
  {
    UINT nFrames = (m_pCurrentSample.p->GetActualDataLength() - m_nSampleOffset) / m_pInputFormat->Format.nBlockAlign;
    rtDuration += nFrames * UNITS / m_pInputFormat->Format.nSamplesPerSec;
  }

  return rtDuration;
}
Ejemplo n.º 25
0
/**
 * The thread method that handles calling send for the individual sockets.
 *
 * Control packets will always be tried to be sent first. If there is any bandwidth leftover
 * after that, send() for the upload slot sockets will be called in priority order until we have run
 * out of available bandwidth for this loop. Upload slots will not be allowed to go without having sent
 * called for more than a defined amount of time (i.e. two seconds).
 *
 * @return always returns 0.
 */
void* UploadBandwidthThrottler::Entry()
{
	const uint32 TIME_BETWEEN_UPLOAD_LOOPS = 1;
	
	uint32 lastLoopTick = GetTickCountFullRes();
	// Bytes to spend in current cycle. If we spend more this becomes negative and causes a wait next time.
	sint32 bytesToSpend = 0;
	uint32 allowedDataRate = 0;
	uint32 rememberedSlotCounter = 0;
	uint32 extraSleepTime = TIME_BETWEEN_UPLOAD_LOOPS;
	
	while (m_doRun && !TestDestroy()) {
		uint32 timeSinceLastLoop = GetTickCountFullRes() - lastLoopTick;

		// Calculate data rate
		if (thePrefs::GetMaxUpload() == UNLIMITED) {
			// Try to increase the upload rate from UploadSpeedSense
			allowedDataRate = (uint32)theStats::GetUploadRate() + 5 * 1024;
		} else {
			allowedDataRate = thePrefs::GetMaxUpload() * 1024;
		}

		uint32 minFragSize = 1300;
		uint32 doubleSendSize = minFragSize*2; // send two packages at a time so they can share an ACK
		if (allowedDataRate < 6*1024) {
			minFragSize = 536;
			doubleSendSize = minFragSize; // don't send two packages at a time at very low speeds to give them a smoother load
		}


		uint32 sleepTime;
		if (bytesToSpend < 1) {
			// We have sent more than allowed in last cycle so we have to wait now
			// until we can send at least 1 byte.
			sleepTime = std::max((-bytesToSpend + 1) * 1000 / allowedDataRate + 2, // add 2 ms to allow for rounding inaccuracies
									extraSleepTime);
		} else {
			// We could send at once, but sleep a while to not suck up all cpu
			sleepTime = extraSleepTime;
		}

		if (timeSinceLastLoop < sleepTime) {
			Sleep(sleepTime-timeSinceLastLoop);
		}

		// Check after sleep in case the thread has been signaled to end
		if (!m_doRun || TestDestroy()) {
			break;
		}

		const uint32 thisLoopTick = GetTickCountFullRes();
		timeSinceLastLoop = thisLoopTick - lastLoopTick;
		lastLoopTick = thisLoopTick;

		if (timeSinceLastLoop > sleepTime + 2000) {
			AddDebugLogLineN(logGeneral, CFormat(wxT("UploadBandwidthThrottler: Time since last loop too long. time: %ims wanted: %ims Max: %ims")) 
				% timeSinceLastLoop % sleepTime % (sleepTime + 2000));

			timeSinceLastLoop = sleepTime + 2000;
		}

		// Calculate how many bytes we can spend

		bytesToSpend += (sint32) (allowedDataRate / 1000.0 * timeSinceLastLoop);

		if (bytesToSpend >= 1) {
			sint32 spentBytes = 0;
			sint32 spentOverhead = 0;

			wxMutexLocker sendLock(m_sendLocker);

			{
				wxMutexLocker queueLock(m_tempQueueLocker);

				// are there any sockets in m_TempControlQueue_list? Move them to normal m_ControlQueue_list;
				m_ControlQueueFirst_list.insert(	m_ControlQueueFirst_list.end(),
													m_TempControlQueueFirst_list.begin(),
													m_TempControlQueueFirst_list.end() );

				m_ControlQueue_list.insert( m_ControlQueue_list.end(), 
											m_TempControlQueue_list.begin(),
											m_TempControlQueue_list.end() );

				m_TempControlQueue_list.clear();
				m_TempControlQueueFirst_list.clear();
			}
	
			// Send any queued up control packets first
			while (spentBytes < bytesToSpend && (!m_ControlQueueFirst_list.empty() || !m_ControlQueue_list.empty())) {
				ThrottledControlSocket* socket = NULL;
	
				if (!m_ControlQueueFirst_list.empty()) {
					socket = m_ControlQueueFirst_list.front();
					m_ControlQueueFirst_list.pop_front();
				} else if (!m_ControlQueue_list.empty()) {
					socket = m_ControlQueue_list.front();
					m_ControlQueue_list.pop_front();
				}
	
				if (socket != NULL) {
					SocketSentBytes socketSentBytes = socket->SendControlData(bytesToSpend-spentBytes, minFragSize);
					spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets;
					spentOverhead += socketSentBytes.sentBytesControlPackets;
				}
			}
	
			// Check if any sockets haven't gotten data for a long time. Then trickle them a package.
			uint32 slots = m_StandardOrder_list.size();
			for (uint32 slotCounter = 0; slotCounter < slots; slotCounter++) {
				ThrottledFileSocket* socket = m_StandardOrder_list[ slotCounter ];
	
				if (socket != NULL) {
					if (thisLoopTick-socket->GetLastCalledSend() > SEC2MS(1)) {
						// trickle
						uint32 neededBytes = socket->GetNeededBytes();
	
						if (neededBytes > 0) {
							SocketSentBytes socketSentBytes = socket->SendFileAndControlData(neededBytes, minFragSize);
							spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets;
							spentOverhead += socketSentBytes.sentBytesControlPackets;
						}
					}
				} else {
					AddDebugLogLineN(logGeneral, CFormat( wxT("There was a NULL socket in the UploadBandwidthThrottler Standard list (trickle)! Prevented usage. Index: %i Size: %i"))
						% slotCounter % m_StandardOrder_list.size());
				}
			}
	
			// Give available bandwidth to slots, starting with the one we ended with last time.
			// There are two passes. First pass gives packets of doubleSendSize, second pass
			// gives as much as possible.
			// Second pass starts with the last slot of the first pass actually.
			for (uint32 slotCounter = 0; (slotCounter < slots * 2) && spentBytes < bytesToSpend; slotCounter++) {
				if (rememberedSlotCounter >= slots) {	// wrap around pointer
					rememberedSlotCounter = 0;
				}

				uint32 data = (slotCounter < slots - 1)	? doubleSendSize				// pass 1
															: (bytesToSpend - spentBytes);	// pass 2

				ThrottledFileSocket* socket = m_StandardOrder_list[ rememberedSlotCounter ];

				if (socket != NULL) {
					SocketSentBytes socketSentBytes = socket->SendFileAndControlData(data, doubleSendSize);
					spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets;
					spentOverhead += socketSentBytes.sentBytesControlPackets;
				} else {
					AddDebugLogLineN(logGeneral, CFormat(wxT("There was a NULL socket in the UploadBandwidthThrottler Standard list (equal-for-all)! Prevented usage. Index: %i Size: %i"))
						% rememberedSlotCounter % m_StandardOrder_list.size());
				}

				rememberedSlotCounter++;
			}

			// Do some limiting of what we keep for the next loop.
			bytesToSpend -= spentBytes;
			sint32 minBytesToSpend = (slots + 1) * minFragSize;

			if (bytesToSpend < - minBytesToSpend) {
				bytesToSpend = - minBytesToSpend;
			} else {
				sint32 bandwidthSavedTolerance = slots * 512 + 1;
				if (bytesToSpend > bandwidthSavedTolerance) {
					bytesToSpend = bandwidthSavedTolerance;
				}
			}
			
			m_SentBytesSinceLastCall += spentBytes;
			m_SentBytesSinceLastCallOverhead += spentOverhead;

			if (spentBytes == 0) {	// spentBytes includes the overhead
				extraSleepTime = std::min<uint32>(extraSleepTime * 5, 1000); // 1s at most
			} else {
				extraSleepTime = TIME_BETWEEN_UPLOAD_LOOPS;
			}
		}
	}

	{
		wxMutexLocker queueLock(m_tempQueueLocker);
		m_TempControlQueue_list.clear();
		m_TempControlQueueFirst_list.clear();
	}

	wxMutexLocker sendLock(m_sendLocker);
	m_ControlQueue_list.clear();
	m_StandardOrder_list.clear();

	return 0;
}
Ejemplo n.º 26
0
void MemoryMapBuilderCS::run()
{
    _interrupted = false;
    // Holds the data that is shared among all threads
    BuilderSharedState* shared = _map->_shared;

    MemoryMapNode* node = 0;

    // Now work through the whole stack
    QMutexLocker queueLock(&shared->queueLock);
    while ( !_interrupted && !shared->queue.isEmpty() &&
//            shared->processed < 1000 &&
            (!shared->lastNode ||
             shared->lastNode->probability() >= shared->minProbability) )
    {
        // Take element with highest probability
        node = shared->queue.takeLargest();
        shared->lastNode = node;
        ++shared->processed;
        queueLock.unlock();

        // try to save the physical mapping
        try {
            int pageSize;
            quint64 physAddr = _map->_vmem->virtualToPhysical(node->address(), &pageSize);
            // Linear memory region or paged memory?
            if (pageSize < 0) {
                PhysMemoryMapNode pNode(
                            physAddr,
                            node->size() > 0 ? physAddr + node->size() - 1 : physAddr,
                            node);
                shared->pmemMapLock.lockForWrite();
                _map->_pmemMap.insert(pNode);
                shared->pmemMapLock.unlock();
            }
            else {
                // Add all pages a type belongs to
                quint32 size = node->size();
                quint64 virtAddr = node->address();
                quint64 pageMask = ~(pageSize - 1);

                while (size > 0) {
                    physAddr = _map->_vmem->virtualToPhysical(virtAddr, &pageSize);
                    // How much space is left on current page?
                    quint32 sizeOnPage = pageSize - (virtAddr & ~pageMask);
                    if (sizeOnPage > size)
                        sizeOnPage = size;
                    PhysMemoryMapNode pNode(
                                physAddr, physAddr + sizeOnPage - 1, node);

                    // Add a memory mapping
                    shared->pmemMapLock.lockForWrite();
                    _map->_pmemMap.insert(pNode);
                    shared->pmemMapLock.unlock();
                    // Subtract the available space from left-over size
                    size -= sizeOnPage;
                    // Advance address
                    virtAddr += sizeOnPage;
                }
            }
        }
        catch (VirtualMemoryException&) {
            // Lock the mutex again before we jump to the loop condition checking
            queueLock.relock();
            // Don't proceed any further in case of an exception
            continue;
        }

        processNode(node);

        // Lock the mutex again before we jump to the loop condition checking
        queueLock.relock();
    }
}
Ejemplo n.º 27
0
DWORD COverlayRenderer::ScheduleThread()
{
  const DWORD eventArraySize = 4;

  HANDLE handles[eventArraySize];
  handles[0] = m_hStopThreadEvent;
  handles[1] = m_hOverlayTimerIG;
  handles[2] = m_hOverlayTimerPG;
  handles[3] = m_hNewOverlayAvailable;

  DWORD stopThread = WAIT_OBJECT_0;
  DWORD processOverlayIG = WAIT_OBJECT_0 + 1;
  DWORD processOverlayPG = WAIT_OBJECT_0 + 2;
  DWORD newOverlayAvailable = WAIT_OBJECT_0 + 3;

  while (true)
  {
    ScheduleOverlays();

    DWORD result = WaitForMultipleObjects(eventArraySize, handles, false, INFINITE);

    if (result == WAIT_FAILED)
      return 0;
    else if (result == stopThread)
      return 0;
    else if(result == newOverlayAvailable)
    {
      CAutoLock queueLock(&m_csOverlayQueue);
      ResetEvent(m_hNewOverlayAvailable);
#ifdef LOG_DRAWING
      LogDebug("newOverlayAvailable");
#endif
    }
    else if (result == processOverlayIG || result == processOverlayPG)
    {
      UINT8 plane = result == processOverlayIG ? BD_OVERLAY_IG : BD_OVERLAY_PG;

      CAutoLock queueLock(&m_csOverlayQueue);

      if (!m_overlayQueue[plane].empty())
      {
        ivecOverlayQueue it = m_overlayQueue[plane].begin();

        if ((*it))
        {
  #ifdef LOG_DRAWING
          LogDebug("RENDERING PTS: %6.3f", (CONVERT_90KHz_DS((*it)->pts) + m_rtOffset) / 10000000.0);
  #endif

          // close frees all overlays
          bool freeOverlay = (*it)->cmd != BD_OVERLAY_CLOSE;

          ProcessOverlay((*it));

          if (freeOverlay)
            FreeOverlay(it);
        }
        else
          FreeOverlay(it);
      }
    }
  }
  
  return 0;
}
Ejemplo n.º 28
0
size_t TaskDispatcher2::queuedTaskCount() const {
	std::lock_guard<std::mutex> queueLock(m_queueMutex);
	return m_taskQueue.size();
}
Ejemplo n.º 29
0
void TaskDispatcher2::removeAllTasks() {
	std::queue<TaskJob> emptyQueue;
	std::lock_guard<std::mutex> queueLock(m_queueMutex);
	std::swap(m_taskQueue, emptyQueue);
}