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.

126 lines
3.1KB

  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. void* open(const char* const filename) noexcept
  28. {
  29. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  30. // try duplicating filename first, it can throw
  31. const char* dfilename = nullptr;
  32. try {
  33. dfilename = carla_strdup(filename);
  34. }
  35. catch(...) {
  36. return nullptr;
  37. }
  38. const CarlaMutexLocker sl(fMutex);
  39. for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
  40. {
  41. Lib& lib(it.getValue());
  42. CARLA_ASSERT(lib.count > 0);
  43. CARLA_SAFE_ASSERT_CONTINUE(lib.filename != nullptr);
  44. if (std::strcmp(lib.filename, filename) == 0)
  45. {
  46. ++lib.count;
  47. return lib.lib;
  48. }
  49. }
  50. void* const libPtr(lib_open(filename));
  51. if (libPtr == nullptr)
  52. return nullptr;
  53. Lib lib;
  54. lib.lib = libPtr;
  55. lib.filename = dfilename;
  56. lib.count = 1;
  57. fLibs.append(lib);
  58. return libPtr;
  59. }
  60. bool close(void* const libPtr) noexcept
  61. {
  62. CARLA_SAFE_ASSERT_RETURN(libPtr != nullptr, false);
  63. const CarlaMutexLocker sl(fMutex);
  64. for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
  65. {
  66. Lib& lib(it.getValue());
  67. CARLA_ASSERT(lib.count > 0);
  68. CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr);
  69. if (lib.lib != libPtr)
  70. continue;
  71. if (--lib.count == 0)
  72. {
  73. if (lib.filename != nullptr)
  74. {
  75. delete[] lib.filename;
  76. lib.filename = nullptr;
  77. }
  78. lib_close(lib.lib);
  79. lib.lib = nullptr;
  80. fLibs.remove(it);
  81. }
  82. return true;
  83. }
  84. CARLA_ASSERT(false); // invalid pointer
  85. return false;
  86. }
  87. private:
  88. struct Lib {
  89. void* lib;
  90. const char* filename;
  91. int count;
  92. };
  93. CarlaMutex fMutex;
  94. LinkedList<Lib> fLibs;
  95. };
  96. // -----------------------------------------------------------------------
  97. #endif // CARLA_LIB_COUNTER_HPP_INCLUDED