Thread.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../Core/Thread.h"
  5. #ifdef _WIN32
  6. #include "../Engine/WinWrapped.h"
  7. #else
  8. #include <pthread.h>
  9. #endif
  10. #include "../DebugNew.h"
  11. namespace Urho3D
  12. {
  13. #ifdef URHO3D_THREADING
  14. #ifdef _WIN32
  15. static DWORD WINAPI ThreadFunctionStatic(void* data)
  16. {
  17. Thread* thread = static_cast<Thread*>(data);
  18. thread->ThreadFunction();
  19. return 0;
  20. }
  21. #else
  22. static void* ThreadFunctionStatic(void* data)
  23. {
  24. auto* thread = static_cast<Thread*>(data);
  25. thread->ThreadFunction();
  26. pthread_exit((void*)nullptr);
  27. return nullptr;
  28. }
  29. #endif
  30. #endif // URHO3D_THREADING
  31. ThreadID Thread::mainThreadID;
  32. Thread::Thread() :
  33. handle_(nullptr),
  34. shouldRun_(false)
  35. {
  36. }
  37. Thread::~Thread()
  38. {
  39. Stop();
  40. }
  41. bool Thread::Run()
  42. {
  43. #ifdef URHO3D_THREADING
  44. // Check if already running
  45. if (handle_)
  46. return false;
  47. shouldRun_ = true;
  48. #ifdef _WIN32
  49. handle_ = CreateThread(nullptr, 0, ThreadFunctionStatic, this, 0, nullptr);
  50. #else
  51. handle_ = new pthread_t;
  52. pthread_attr_t type;
  53. pthread_attr_init(&type);
  54. pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
  55. pthread_create((pthread_t*)handle_, &type, ThreadFunctionStatic, this);
  56. #endif
  57. return handle_ != nullptr;
  58. #else
  59. return false;
  60. #endif // URHO3D_THREADING
  61. }
  62. void Thread::Stop()
  63. {
  64. #ifdef URHO3D_THREADING
  65. // Check if already stopped
  66. if (!handle_)
  67. return;
  68. shouldRun_ = false;
  69. #ifdef _WIN32
  70. WaitForSingleObject((HANDLE)handle_, INFINITE);
  71. CloseHandle((HANDLE)handle_);
  72. #else
  73. auto* thread = (pthread_t*)handle_;
  74. if (thread)
  75. pthread_join(*thread, nullptr);
  76. delete thread;
  77. #endif
  78. handle_ = nullptr;
  79. #endif // URHO3D_THREADING
  80. }
  81. void Thread::SetPriority(int priority)
  82. {
  83. #ifdef URHO3D_THREADING
  84. #ifdef _WIN32
  85. if (handle_)
  86. SetThreadPriority((HANDLE)handle_, priority);
  87. #elif defined(__linux__) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
  88. auto* thread = (pthread_t*)handle_;
  89. if (thread)
  90. pthread_setschedprio(*thread, priority);
  91. #endif
  92. #endif // URHO3D_THREADING
  93. }
  94. void Thread::SetMainThread()
  95. {
  96. mainThreadID = GetCurrentThreadID();
  97. }
  98. ThreadID Thread::GetCurrentThreadID()
  99. {
  100. #ifdef URHO3D_THREADING
  101. #ifdef _WIN32
  102. return GetCurrentThreadId();
  103. #else
  104. return pthread_self();
  105. #endif
  106. #else
  107. return ThreadID();
  108. #endif // URHO3D_THREADING
  109. }
  110. bool Thread::IsMainThread()
  111. {
  112. #ifdef URHO3D_THREADING
  113. return GetCurrentThreadID() == mainThreadID;
  114. #else
  115. return true;
  116. #endif // URHO3D_THREADING
  117. }
  118. }