You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.3KB

  1. #include "MidiLock.h"
  2. #include <assert.h>
  3. MidiLock::MidiLock()
  4. {
  5. theLock = false;
  6. editorLockLevel = 0;
  7. editorDidLock = false;
  8. }
  9. MidiLockPtr MidiLock::make()
  10. {
  11. return std::make_shared<MidiLock>();
  12. }
  13. void MidiLock::editorLock()
  14. {
  15. if (editorLockLevel == 0) {
  16. // poll to take lock
  17. for (bool done = false; !done; ) {
  18. done = tryLock();
  19. }
  20. }
  21. ++editorLockLevel;
  22. editorDidLock = true;
  23. const int l = editorLockLevel;
  24. }
  25. void MidiLock::editorUnlock()
  26. {
  27. const int l = editorLockLevel;
  28. if (--editorLockLevel == 0) {
  29. theLock = false;
  30. }
  31. }
  32. bool MidiLock::playerTryLock()
  33. {
  34. // try once to take lock
  35. return tryLock();
  36. }
  37. void MidiLock::playerUnlock()
  38. {
  39. assert(locked());
  40. theLock = false;
  41. }
  42. bool MidiLock::tryLock()
  43. {
  44. bool expected = false;
  45. bool desired = true;
  46. bool ret = theLock.compare_exchange_weak(expected, desired);
  47. return ret;
  48. }
  49. bool MidiLock::locked() const
  50. {
  51. return theLock;
  52. }
  53. bool MidiLock::dataModelDirty()
  54. {
  55. bool ret = editorDidLock;
  56. editorDidLock = false;
  57. return ret;
  58. }
  59. /***********************************************************************/
  60. MidiLocker::MidiLocker(MidiLockPtr l) : lock(l)
  61. {
  62. lock->editorLock();
  63. }
  64. MidiLocker::~MidiLocker()
  65. {
  66. lock->editorUnlock();
  67. }