mutex.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifndef MUTEX_H
  19. #define MUTEX_H
  20. #if defined(_MSC_VER)
  21. #pragma once
  22. #endif
  23. #include "always.h"
  24. // Always use mutex or critical section when accessing the same data from multiple threads!
  25. // ----------------------------------------------------------------------------
  26. //
  27. // Mutex class is an expensive way of synchronization! Use critical sections
  28. // (below) for all synchronization. Use mutexes for inter-process locking.
  29. //
  30. // ----------------------------------------------------------------------------
  31. class MutexClass
  32. {
  33. void* handle;
  34. unsigned locked;
  35. // Lock and unlock are private so that you can't use them directly. Use LockClass as a sentry instead!
  36. // Lock returns true if lock was succesful, false otherwise
  37. bool Lock(int time);
  38. void Unlock();
  39. public:
  40. // Name can (and usually should) be NULL. Use name only if you wish to create a globally unique mutex
  41. MutexClass(const char* name = NULL);
  42. ~MutexClass();
  43. enum {
  44. WAIT_INFINITE=-1
  45. };
  46. class LockClass
  47. {
  48. MutexClass& mutex;
  49. bool failed;
  50. public:
  51. // In order to lock a mutex create a local instance of LockClass with mutex as a parameter.
  52. // Time is in milliseconds, INFINITE means infinite wait.
  53. LockClass(MutexClass& m, int time=MutexClass::WAIT_INFINITE);
  54. ~LockClass();
  55. // Returns true if the lock failed
  56. bool Failed() { return failed; }
  57. private:
  58. LockClass &operator=(const LockClass&) { return(*this); }
  59. };
  60. friend class LockClass;
  61. };
  62. // ----------------------------------------------------------------------------
  63. //
  64. // Critical sections are faster than mutex classes and they should be used
  65. // for all synchronization.
  66. //
  67. // ----------------------------------------------------------------------------
  68. class CriticalSectionClass
  69. {
  70. void* handle;
  71. unsigned locked;
  72. // Lock and unlock are private so that you can't use them directly. Use LockClass as a sentry instead!
  73. void Lock();
  74. void Unlock();
  75. public:
  76. // Name can (and usually should) be NULL. Use name only if you wish to create a globally unique mutex
  77. CriticalSectionClass();
  78. ~CriticalSectionClass();
  79. class LockClass
  80. {
  81. CriticalSectionClass& CriticalSection;
  82. public:
  83. // In order to lock a mutex create a local instance of LockClass with mutex as a parameter.
  84. // Time is in milliseconds, INFINITE means infinite wait.
  85. LockClass(CriticalSectionClass& c);
  86. ~LockClass();
  87. private:
  88. LockClass &operator=(const LockClass&) { return(*this); }
  89. };
  90. friend class LockClass;
  91. };
  92. #endif