tasks.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "tasks.h"
  2. #include <time.h>
  3. // Here's some information on pthread_mutex:
  4. // https://www.ibm.com/support/knowledgecenter/ssw_aix_72/p_bostechref/pthread_mutex_timedlock.html
  5. tasks::tasks()
  6. {
  7. chatroom_tasks = new concurrent_queue<task *>();
  8. queue_mutex = PTHREAD_MUTEX_INITIALIZER;
  9. pthread_mutex_init(&queue_mutex,NULL);
  10. pthread_mutex_lock(&queue_mutex);
  11. }
  12. tasks::~tasks()
  13. {
  14. delete chatroom_tasks;
  15. chatroom_tasks = nullptr;
  16. pthread_mutex_destroy(&queue_mutex);
  17. }
  18. void tasks::wait_for_tasks(int delay_in_seconds)
  19. {
  20. // This function waits for a task.
  21. // Just because this function returns, doesn't mean there's a task.
  22. // This was on purpose to prevent a race condition.
  23. // If there's a task waiting, this function returns immediately.
  24. // If no task is waiting, this function returns in 1 second.
  25. struct timespec abs_timeout;
  26. if (!chatroom_tasks->empty())
  27. {
  28. return;
  29. }
  30. if (delay_in_seconds <=0) {
  31. pthread_mutex_lock(&queue_mutex);
  32. } else {
  33. timespec_get(&abs_timeout,TIME_UTC);
  34. abs_timeout.tv_sec += delay_in_seconds;
  35. pthread_mutex_timedlock(&queue_mutex,&abs_timeout);
  36. }
  37. if (!chatroom_tasks->empty()) {
  38. // If there are tasks, then the mutex should be unlocked.
  39. pthread_mutex_trylock(&queue_mutex); // Make sure it's locked so unlock doesn't fail if it's already unlocked.
  40. pthread_mutex_unlock(&queue_mutex);
  41. }
  42. return;
  43. }
  44. void tasks::add_task(task *task)
  45. {
  46. bool was_queue_empty;
  47. was_queue_empty = chatroom_tasks->empty();
  48. chatroom_tasks->enqueue(task);
  49. if (was_queue_empty) {
  50. // Unlock the mutex to show that something is now on the queue.
  51. pthread_mutex_trylock(&queue_mutex); // Make sure it's locked so unlock doesn't fail if it's already unlocked.
  52. pthread_mutex_unlock(&queue_mutex);
  53. }
  54. return;
  55. }
  56. void tasks::do_tasks()
  57. {
  58. // sometimes tasks create other tasks.
  59. // If run_async is false, this routine is called to make sure every task runs.
  60. task *next_task;
  61. while (!chatroom_tasks->empty())
  62. {
  63. chatroom_tasks->dequeue(next_task);
  64. next_task->dotask();
  65. delete next_task;
  66. }
  67. // The queue should be empty. Try to lock it.
  68. pthread_mutex_trylock(&queue_mutex);
  69. return;
  70. }