Audio plugin host https://kx.studio/carla
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.

160 lines
4.2KB

  1. /*
  2. * Carla library counter
  3. * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_LIB_COUNTER_HPP_INCLUDED
  18. #define CARLA_LIB_COUNTER_HPP_INCLUDED
  19. #include "CarlaLibUtils.hpp"
  20. #include "CarlaMutex.hpp"
  21. #include "LinkedList.hpp"
  22. // -----------------------------------------------------------------------
  23. class LibCounter
  24. {
  25. public:
  26. LibCounter() noexcept {}
  27. ~LibCounter() noexcept
  28. {
  29. // might have some leftovers
  30. for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
  31. {
  32. Lib& lib(it.getValue());
  33. CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0);
  34. CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr);
  35. if (! lib_close(lib.lib))
  36. carla_stderr("LibCounter cleanup failed, reason:\n%s", lib_error(lib.filename));
  37. lib.lib = nullptr;
  38. if (lib.filename != nullptr)
  39. {
  40. delete[] lib.filename;
  41. lib.filename = nullptr;
  42. }
  43. }
  44. fLibs.clear();
  45. }
  46. void* open(const char* const filename, const bool canDelete = true) noexcept
  47. {
  48. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  49. // try duplicating filename first, it can throw
  50. const char* dfilename = nullptr;
  51. try {
  52. dfilename = carla_strdup(filename);
  53. }
  54. CARLA_SAFE_EXCEPTION_RETURN("LibCounter::open", nullptr);
  55. const CarlaMutexLocker sl(fMutex);
  56. for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
  57. {
  58. Lib& lib(it.getValue());
  59. CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0);
  60. CARLA_SAFE_ASSERT_CONTINUE(lib.filename != nullptr);
  61. if (std::strcmp(lib.filename, filename) == 0)
  62. {
  63. ++lib.count;
  64. return lib.lib;
  65. }
  66. }
  67. void* const libPtr(lib_open(filename));
  68. if (libPtr == nullptr)
  69. {
  70. delete[] dfilename;
  71. return nullptr;
  72. }
  73. Lib lib;
  74. lib.lib = libPtr;
  75. lib.filename = dfilename;
  76. lib.count = 1;
  77. lib.canDelete = canDelete;
  78. if (fLibs.append(lib))
  79. return libPtr;
  80. delete[] dfilename;
  81. return nullptr;
  82. }
  83. bool close(void* const libPtr) noexcept
  84. {
  85. CARLA_SAFE_ASSERT_RETURN(libPtr != nullptr, false);
  86. const CarlaMutexLocker sl(fMutex);
  87. for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
  88. {
  89. Lib& lib(it.getValue());
  90. CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0);
  91. CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr);
  92. if (lib.lib != libPtr)
  93. continue;
  94. if (lib.count == 1 && ! lib.canDelete)
  95. return true;
  96. if (--lib.count == 0)
  97. {
  98. if (! lib_close(lib.lib))
  99. carla_stderr("LibCounter::close() failed, reason:\n%s", lib_error(lib.filename));
  100. lib.lib = nullptr;
  101. if (lib.filename != nullptr)
  102. {
  103. delete[] lib.filename;
  104. lib.filename = nullptr;
  105. }
  106. fLibs.remove(it);
  107. }
  108. return true;
  109. }
  110. carla_safe_assert("invalid lib pointer", __FILE__, __LINE__);
  111. return false;
  112. }
  113. private:
  114. struct Lib {
  115. void* lib;
  116. const char* filename;
  117. int count;
  118. bool canDelete;
  119. };
  120. CarlaMutex fMutex;
  121. LinkedList<Lib> fLibs;
  122. };
  123. // -----------------------------------------------------------------------
  124. #endif // CARLA_LIB_COUNTER_HPP_INCLUDED