ThreadFunctions.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "ThreadFunctions.h"
  2. #include "threadpool_types.h"
  3. ThreadFunctions::ThreadFunctions(int create_function_list)
  4. {
  5. if (create_function_list)
  6. {
  7. functions_semaphore = CreateSemaphore(0, 0, ThreadPoolTypes::MAX_SEMAPHORE_VALUE, 0);
  8. InitializeCriticalSectionAndSpinCount(&functions_guard, 200);
  9. }
  10. else
  11. functions_semaphore = 0;
  12. }
  13. ThreadFunctions::~ThreadFunctions()
  14. {
  15. if (functions_semaphore)
  16. {
  17. CloseHandle(functions_semaphore);
  18. DeleteCriticalSection(&functions_guard);
  19. }
  20. }
  21. void ThreadFunctions::Add(HANDLE handle, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id)
  22. {
  23. Nullsoft::Utility::AutoLock l(guard);
  24. Data *new_data = (Data *)calloc(1, sizeof(Data));
  25. new_data->func = func;
  26. new_data->user_data = user_data;
  27. new_data->id = id;
  28. data[handle] = new_data;
  29. }
  30. bool ThreadFunctions::Get(HANDLE handle, api_threadpool::ThreadPoolFunc *func, void **user_data, intptr_t *id)
  31. {
  32. Nullsoft::Utility::AutoLock l(guard);
  33. DataMap::iterator found = data.find(handle);
  34. if (found == data.end())
  35. return false;
  36. const Data *d = found->second;
  37. *func = d->func;
  38. *user_data = d->user_data;
  39. *id = d->id;
  40. return true;
  41. }
  42. void ThreadFunctions::QueueFunction(api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id)
  43. {
  44. Data *new_data = (Data *)calloc(1, sizeof(Data));
  45. new_data->func = func;
  46. new_data->user_data = user_data;
  47. new_data->id = id;
  48. EnterCriticalSection(&functions_guard);
  49. functions_list.push_front(new_data);
  50. LeaveCriticalSection(&functions_guard); // unlock before releasing the semaphore early so we don't lock convoy
  51. ReleaseSemaphore(functions_semaphore, 1, 0);
  52. }
  53. bool ThreadFunctions::PopFunction(api_threadpool::ThreadPoolFunc *func, void **user_data, intptr_t *id)
  54. {
  55. EnterCriticalSection(&functions_guard);
  56. if (!functions_list.empty())
  57. {
  58. ThreadFunctions::Data *data = functions_list.back();
  59. functions_list.pop_back();
  60. LeaveCriticalSection(&functions_guard);
  61. *func = data->func;
  62. *user_data = data->user_data;
  63. *id = data->id;
  64. free(data);
  65. return true;
  66. }
  67. else
  68. {
  69. LeaveCriticalSection(&functions_guard);
  70. return false;
  71. }
  72. }