2 * Carla library counter
3 * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
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.
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.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_LIB_COUNTER_HPP_INCLUDED
19 #define CARLA_LIB_COUNTER_HPP_INCLUDED
21 #include "CarlaLibUtils.hpp"
22 #include "CarlaMutex.hpp"
23 #include "LinkedList.hpp"
25 // -----------------------------------------------------------------------
34 ~LibCounter() noexcept
36 // might have some leftovers
37 for (LinkedList
<Lib
>::Itenerator it
= fLibs
.begin2(); it
.valid(); it
.next())
39 static Lib libFallback
= { nullptr, nullptr, 0, false };
41 Lib
& lib(it
.getValue(libFallback
));
42 CARLA_SAFE_ASSERT_CONTINUE(lib
.count
> 0);
43 CARLA_SAFE_ASSERT_CONTINUE(lib
.lib
!= nullptr);
45 // all libs should be closed by now except those explicitly marked non-delete
46 CARLA_SAFE_ASSERT(! lib
.canDelete
);
48 if (! lib_close(lib
.lib
))
49 carla_stderr("LibCounter cleanup failed, reason:\n%s", lib_error(lib
.filename
));
53 if (lib
.filename
!= nullptr)
55 delete[] lib
.filename
;
56 lib
.filename
= nullptr;
63 lib_t
open(const char* const filename
, const bool canDelete
= true) noexcept
65 CARLA_SAFE_ASSERT_RETURN(filename
!= nullptr && filename
[0] != '\0', nullptr);
67 // try duplicating filename first, it can throw
68 const char* dfilename
= nullptr;
71 dfilename
= carla_strdup(filename
);
72 } CARLA_SAFE_EXCEPTION_RETURN("LibCounter::open", nullptr);
74 const CarlaMutexLocker
cml(fMutex
);
76 for (LinkedList
<Lib
>::Itenerator it
= fLibs
.begin2(); it
.valid(); it
.next())
78 static Lib libFallback
= { nullptr, nullptr, 0, false };
80 Lib
& lib(it
.getValue(libFallback
));
81 CARLA_SAFE_ASSERT_CONTINUE(lib
.count
> 0);
82 CARLA_SAFE_ASSERT_CONTINUE(lib
.filename
!= nullptr);
84 if (std::strcmp(lib
.filename
, filename
) == 0)
94 const lib_t libPtr
= lib_open(filename
);
96 if (libPtr
== nullptr)
104 lib
.filename
= dfilename
;
106 lib
.canDelete
= canDelete
;
108 lib
.canDelete
= true;
111 if (fLibs
.append(lib
))
118 bool close(const lib_t libPtr
) noexcept
120 CARLA_SAFE_ASSERT_RETURN(libPtr
!= nullptr, false);
122 const CarlaMutexLocker
cml(fMutex
);
124 for (LinkedList
<Lib
>::Itenerator it
= fLibs
.begin2(); it
.valid(); it
.next())
126 static Lib libFallback
= { nullptr, nullptr, 0, false };
128 Lib
& lib(it
.getValue(libFallback
));
129 CARLA_SAFE_ASSERT_CONTINUE(lib
.count
> 0);
130 CARLA_SAFE_ASSERT_CONTINUE(lib
.lib
!= nullptr);
132 if (lib
.lib
!= libPtr
)
135 if (lib
.count
== 1 && ! lib
.canDelete
)
138 if (--lib
.count
== 0)
140 if (! lib_close(lib
.lib
))
141 carla_stderr("LibCounter::close() failed, reason:\n%s", lib_error(lib
.filename
));
145 if (lib
.filename
!= nullptr)
147 delete[] lib
.filename
;
148 lib
.filename
= nullptr;
157 carla_safe_assert("invalid lib pointer", __FILE__
, __LINE__
);
161 void setCanDelete(const lib_t libPtr
, const bool canDelete
)
163 CARLA_SAFE_ASSERT_RETURN(libPtr
!= nullptr,);
165 const CarlaMutexLocker
cml(fMutex
);
167 for (LinkedList
<Lib
>::Itenerator it
= fLibs
.begin2(); it
.valid(); it
.next())
169 static Lib libFallback
= { nullptr, nullptr, 0, false };
171 Lib
& lib(it
.getValue(libFallback
));
172 CARLA_SAFE_ASSERT_CONTINUE(lib
.lib
!= nullptr);
174 if (lib
.lib
!= libPtr
)
177 lib
.canDelete
= canDelete
;
185 const char* filename
;
191 LinkedList
<Lib
> fLibs
;
194 // -----------------------------------------------------------------------
196 #endif // CARLA_LIB_COUNTER_HPP_INCLUDED