2
0

runguard.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. *openPilotLog - A FOSS Pilot Logbook Application
  3. *Copyright (C) 2020-2023 Felix Turowsky
  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 <https://www.gnu.org/licenses/>.
  17. */
  18. #include "runguard.h"
  19. #include <QCryptographicHash>
  20. namespace
  21. {
  22. QString generateKeyHash(const QString &key, const QString &salt)
  23. {
  24. QByteArray data;
  25. data.append(key.toUtf8());
  26. data.append(salt.toUtf8());
  27. data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
  28. return data;
  29. }
  30. }
  31. RunGuard::RunGuard(const QString &key )
  32. : key(key )
  33. , memLockKey(generateKeyHash(key, "_memLockKey" ))
  34. , sharedmemKey(generateKeyHash(key, "_sharedmemKey" ))
  35. , sharedMem(sharedmemKey )
  36. , memLock(memLockKey, 1 )
  37. {
  38. memLock.acquire();
  39. {
  40. QSharedMemory fix(sharedmemKey ); // Fix for *nix: http://habrahabr.ru/post/173281/
  41. fix.attach();
  42. }
  43. memLock.release();
  44. }
  45. RunGuard::~RunGuard()
  46. {
  47. release();
  48. }
  49. bool RunGuard::isAnotherRunning()
  50. {
  51. if (sharedMem.isAttached())
  52. return false;
  53. memLock.acquire();
  54. const bool isRunning = sharedMem.attach();
  55. if (isRunning )
  56. sharedMem.detach();
  57. memLock.release();
  58. return isRunning;
  59. }
  60. bool RunGuard::tryToRun()
  61. {
  62. if (isAnotherRunning()) // Extra check
  63. return false;
  64. memLock.acquire();
  65. const bool result = sharedMem.create(sizeof(quint64 ));
  66. memLock.release();
  67. if (!result )
  68. {
  69. release();
  70. return false;
  71. }
  72. return true;
  73. }
  74. void RunGuard::release()
  75. {
  76. memLock.acquire();
  77. if (sharedMem.isAttached())
  78. sharedMem.detach();
  79. memLock.release();
  80. }