Beispiel #1
0
bool
Thread::Start()
{
  assert(!IsDefined());

#ifdef HAVE_POSIX
#ifndef NDEBUG
  creating = true;
#endif

  defined = pthread_create(&handle, NULL, ThreadProc, this) == 0;

#ifndef NDEBUG
  creating = false;
#endif

  bool success = defined;
#else
  handle = ::CreateThread(NULL, 0, ThreadProc, this, 0, &id);

  bool success = handle != NULL;
#endif

#ifndef NDEBUG
  if (success) {
    all_threads_mutex.Lock();
    siblings.InsertAfter(all_threads);
    all_threads_mutex.Unlock();
  }
#endif

  return success;
}
Beispiel #2
0
 /**
  * Determine if the current thread has locked this mutex.  This is a
  * debug-only method meant for assert() calls, and is not available
  * in optimised builds.
  */
 gcc_pure
 bool IsLockedByCurrent() const {
   debug_mutex.Lock();
   bool result = locked && owner.IsInside();
   debug_mutex.Unlock();
   return result;
 }
Beispiel #3
0
bool
Thread::Start()
{
  assert(!IsDefined());

#ifdef HAVE_POSIX
#ifndef NDEBUG
  creating = true;
#endif

  defined = pthread_create(&handle, nullptr, ThreadProc, this) == 0;

#ifndef NDEBUG
  creating = false;
#endif

  bool success = defined;
#else
  handle = ::CreateThread(nullptr, 0, ThreadProc, this, 0, &id);

  bool success = handle != nullptr;
#endif

#ifndef NDEBUG
  if (success) {
    all_threads_mutex.lock();
    all_threads.push_back(*this);
    all_threads_mutex.unlock();
  }
#endif

  return success;
}
Beispiel #4
0
void DatabaseThread::AddRequest(Packet * pkt)
{
	_lock.Acquire();
	_queue.push(pkt);
	_lock.Release();
	s_hEvent.Signal();
}
Beispiel #5
0
void PooledThread::join()
{
	_mutex.lock();
	Runnable* pTarget = _pTarget;
	_mutex.unlock();
	if (pTarget)
		_targetCompleted.wait();
}
Beispiel #6
0
bool
ExistsAnyThread()
{
  all_threads_mutex.lock();
  bool result = !all_threads.empty();
  all_threads_mutex.unlock();
  return result;
}
Beispiel #7
0
bool
ExistsAnyThread()
{
  all_threads_mutex.Lock();
  bool result = !all_threads.IsEmpty();
  all_threads_mutex.Unlock();
  return result;
}
Beispiel #8
0
  /**
   * Unlocks the Mutex
   */
  void Unlock() {
#ifndef NDEBUG
    debug_mutex.lock();
    assert(locked);
    assert(owner.IsInside());
    locked = false;
    debug_mutex.unlock();
#endif

    mutex.unlock();
  }
Beispiel #9
0
void PooledThread::release()
{
	const long JOIN_TIMEOUT = 10000;
	
	_mutex.lock();
	_pTarget = 0;
	_mutex.unlock();

	_targetReady.set();
	if (_thread.tryJoin(JOIN_TIMEOUT))
	{
		delete this;
	}
}
Beispiel #10
0
void PooledThread::join(bool bWaitThreadFinish)
{
    m_mutex.lock();
    Runnable* pTarget = m_pTarget;
    m_mutex.unlock();
    if (pTarget || !idle())
    {
        m_targetCompleted.wait();
    }
//     if (bWaitThreadFinish && m_thread.isRunning())
//     {
//         m_thread.join();
//     }
}
Beispiel #11
0
  /**
   * Unlocks the Mutex
   */
  void Unlock() {
#ifndef NDEBUG
    debug_mutex.Lock();
    assert(locked);
    assert(owner.IsInside());
    locked = false;
    debug_mutex.Unlock();
#endif

    mutex.Unlock();

#ifndef NDEBUG
    --thread_locks_held;
#endif
  }
Beispiel #12
0
void PooledThread::run()
{
	_started.set();
	for (;;)
	{
		_targetReady.wait();
		_mutex.lock();
		if (_pTarget) // a NULL target means kill yourself
		{
			_mutex.unlock();
			try
			{
				_pTarget->run();
			}
			catch (Exception& exc)
			{
				ErrorHandler::handle(exc);
			}
			catch (std::exception& exc)
			{
				ErrorHandler::handle(exc);
			}
			catch (...)
			{
				ErrorHandler::handle();
			}
			FastMutex::ScopedLock lock(_mutex);
			_pTarget  = 0;
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
			_idleTime = wceex_time(NULL);
#else
			_idleTime = time(NULL);
#endif	
			_idle     = true;
			_targetCompleted.set();
			ThreadLocalStorage::clear();
			_thread.setName(_name);
			_thread.setPriority(Thread::PRIO_NORMAL);
		}
		else
		{
			_mutex.unlock();
			break;
		}
	}
}
Beispiel #13
0
  /**
   * Tries to lock the Mutex
   */
  bool TryLock() {
    if (!mutex.try_lock()) {
#ifndef NDEBUG
      assert(!IsLockedByCurrent());
#endif
      return false;
    }

#ifndef NDEBUG
    debug_mutex.lock();
    assert(!locked);
    locked = true;
    owner = ThreadHandle::GetCurrent();
    debug_mutex.unlock();
#endif
    return true;
  };
Beispiel #14
0
void PooledThread::release()
{
    m_mutex.lock();
    m_pTarget = NULL;
    m_mutex.unlock();

    m_targetReady.set();
    m_thread.join();

    // In case of a statically allocated thread pool (such
    // as the default thread pool), Windows may have already
    // terminated the thread before we got here.
    // if (m_thread.isRunning()) 
    // {
    //     m_targetReady.set();
    // }
}
Beispiel #15
0
void PooledThread::run()
{
    m_started.set();
    for (;;)
    {
        m_targetReady.wait();
        m_mutex.lock();
        if (m_pTarget) // a NULL target means kill yourself
        {
            m_mutex.unlock();
            try
            {
                m_pTarget->run();
            }
            catch (const FirteXException&)
            {
                throw;
            }
            catch (const exception& exc)
            {
                FIRTEX_THROW(RuntimeException, "%s", exc.what());
            }
            catch (...)
            {
                FIRTEX_THROW(RuntimeException, "Unknow exception.");
            }
            FastMutex::Guard lock(m_mutex);
            m_pTarget = NULL;
            m_idleTime = time(NULL);
            m_bIdle = true;
            m_targetCompleted.set();
//	    ThreadLocalStorage::clear();
            m_thread.setName(m_sName);
            m_thread.setPriority(Thread::PRIO_NORMAL);

            m_pool.broadcast();
        }
        else
        {
            m_bIdle = true;
            m_mutex.unlock();
            break;
        }
    }
}
Beispiel #16
0
void
Thread::Join()
{
  assert(IsDefined());
  assert(!IsInside());

#ifdef HAVE_POSIX
  pthread_join(handle, NULL);
  defined = false;
#else
  ::WaitForSingleObject(handle, INFINITE);
  ::CloseHandle(handle);
  handle = NULL;
#endif

#ifndef NDEBUG
  all_threads_mutex.Lock();
  siblings.Remove();
  all_threads_mutex.Unlock();
#endif
}
Beispiel #17
0
void
Thread::Join()
{
  assert(IsDefined());
  assert(!IsInside());

#ifdef HAVE_POSIX
  pthread_join(handle, nullptr);
  defined = false;
#else
  ::WaitForSingleObject(handle, INFINITE);
  ::CloseHandle(handle);
  handle = nullptr;
#endif

#ifndef NDEBUG
  all_threads_mutex.lock();
  all_threads.erase(all_threads.iterator_to(*this));
  all_threads_mutex.unlock();
#endif
}
Beispiel #18
0
  /**
   * Locks the Mutex
   */
  void Lock() {
#ifdef NDEBUG
    mutex.lock();
#else
    if (!mutex.try_lock()) {
      /* locking has failed - at this point, "locked" and "owner" are
         either not yet update, or "owner" is set to another thread */
      assert(!IsLockedByCurrent());

      mutex.lock();
    }

    /* we have just obtained the mutex; the "locked" flag must not be
       set */
    debug_mutex.lock();
    assert(!locked);
    locked = true;
    owner = ThreadHandle::GetCurrent();
    debug_mutex.unlock();
#endif
  };
Beispiel #19
0
bool
Thread::Join(unsigned timeout_ms)
{
  assert(IsDefined());
  assert(!IsInside());

  bool result = ::WaitForSingleObject(handle, timeout_ms) == WAIT_OBJECT_0;
  if (result) {
    ::CloseHandle(handle);
    handle = nullptr;

#ifndef NDEBUG
    {
      all_threads_mutex.lock();
      all_threads.erase(all_threads.iterator_to(*this));
      all_threads_mutex.unlock();
    }
#endif
  }

  return result;
}
Beispiel #20
0
bool
Thread::Join(unsigned timeout_ms)
{
  assert(IsDefined());
  assert(!IsInside());

  bool result = ::WaitForSingleObject(handle, timeout_ms) == WAIT_OBJECT_0;
  if (result) {
    ::CloseHandle(handle);
    handle = NULL;

#ifndef NDEBUG
    {
      all_threads_mutex.Lock();
      siblings.Remove();
      all_threads_mutex.Unlock();
    }
#endif
  }

  return result;
}
Beispiel #21
0
uint32 THREADCALL DatabaseThread::ThreadProc(void * lpParam)
{
	while (true)
	{
		Packet *p = nullptr;

		// Pull the next packet from the shared queue
		_lock.Acquire();
		if (_queue.size())
		{
			p = _queue.front();
			_queue.pop();
		}
		_lock.Release();

		// If there's no more packets to handle, wait until there are.
		if (p == nullptr)
		{
			// If we're shutting down, don't bother waiting for more (there are no more).
			if (!_running)
				break;

			s_hEvent.Wait();
			continue;
		}

		// References are fun =p
		Packet & pkt = *p;

		// First 2 bytes are always going to be the socket ID
		// or -1 for no user.
		int16 uid = pkt.read<int16>();

		// Attempt to lookup the user if necessary
		CUser *pUser = nullptr;
		if (uid >= 0)
		{
			pUser = g_pMain->GetUserPtr(uid);

			// Check to make sure they're still connected.
			if (pUser == nullptr)
				continue;
		}

		uint8 subOpcode;
		switch (pkt.GetOpcode())
		{
		case WIZ_LOGIN:
			if (pUser) pUser->ReqAccountLogIn(pkt);
			break;
		case WIZ_SEL_NATION:
			if (pUser) pUser->ReqSelectNation(pkt);
			break;
		case WIZ_ALLCHAR_INFO_REQ:
			if (pUser) pUser->ReqAllCharInfo(pkt);
			break;
		case WIZ_CHANGE_HAIR:
			if (pUser) pUser->ReqChangeHair(pkt);
			break;
		case WIZ_NEW_CHAR:
			if (pUser) pUser->ReqCreateNewChar(pkt);
			break;
		case WIZ_DEL_CHAR:
			if (pUser) pUser->ReqDeleteChar(pkt);
			break;
		case WIZ_SEL_CHAR:
			if (pUser) pUser->ReqSelectCharacter(pkt);
			break;
		case WIZ_CHAT:
			pkt >> subOpcode;
			if (subOpcode == CLAN_NOTICE)
				CKnightsManager::ReqUpdateClanNotice(pkt);
			break;
		case WIZ_DATASAVE:
			if (pUser) pUser->ReqSaveCharacter();
			break;
		case WIZ_KNIGHTS_PROCESS:
			CKnightsManager::ReqKnightsPacket(pUser, pkt);
			break;
		case WIZ_LOGIN_INFO:
			if (pUser) pUser->ReqSetLogInInfo(pkt);
			break;
		case WIZ_BATTLE_EVENT:
			// g_pMain->BattleEventResult(pkt);
			break;
		case WIZ_SHOPPING_MALL:
			if (pUser) pUser->ReqShoppingMall(pkt);
			break;
		case WIZ_SKILLDATA:
			if (pUser) pUser->ReqSkillDataProcess(pkt);
			break;
		case WIZ_FRIEND_PROCESS:
			if (pUser) pUser->ReqFriendProcess(pkt);
			break;
		case WIZ_NAME_CHANGE:
			if (pUser) pUser->ReqChangeName(pkt);
			break;
		case WIZ_CAPE:
			if (pUser) pUser->ReqChangeCape(pkt);
			break;
		case WIZ_LOGOUT:
			if (pUser) pUser->ReqUserLogOut();
			break;
		case WIZ_KING:
			CKingSystem::HandleDatabaseRequest(pUser, pkt);
			break;
		case WIZ_ITEM_UPGRADE:
			if (pUser) pUser->ReqSealItem(pkt);
			break;
		case WIZ_ZONE_CONCURRENT:
			{
				uint32 serverNo, count;
				pkt >> serverNo >> count;
				g_DBAgent.UpdateConCurrentUserCount(serverNo, 1, count);
			} break;
		}

		// Free the packet.
		delete p;
	}

	TRACE("[Thread %d] Exiting...\n", lpParam);
	return 0;
}