Skip to content

Commit ab387f8

Browse files
committed
Fixes: we were overzealously freeing what we once wished to cheaply leak
Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent dc0d7c5 commit ab387f8

1 file changed

Lines changed: 32 additions & 54 deletions

File tree

src/libutil/ustring.cpp

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,24 @@
1515
#include <OpenImageIO/unordered_map_concurrent.h>
1616
#include <OpenImageIO/ustring.h>
1717

18+
19+
20+
OIIO_NAMESPACE_BEGIN
21+
namespace pvt {
22+
23+
// If nonzero, the ustring table will be freed at process exit. This is off by
24+
// default because cleanup is unnecessary (the OS reclaims the memory) and can
25+
// add measurable time at exit for large tables. Enable it when using valgrind
26+
// or other leak detectors to suppress false positives. Settable via
27+
// OIIO::attribute("ustring:cleanup",1) or the OIIO_USTRING_CLEANUP
28+
// environment variable.
29+
OIIO_UTIL_API int oiio_ustring_cleanup = Strutil::stoi(
30+
Sysutil::getenv("OIIO_USTRING_CLEANUP"));
31+
32+
} // namespace pvt
33+
OIIO_NAMESPACE_END
34+
35+
1836
OIIO_NAMESPACE_3_1_BEGIN
1937

2038
// Use rw spin locks
@@ -47,26 +65,21 @@ template<unsigned BASE_CAPACITY, unsigned POOL_SIZE> struct TableRepMap {
4765
}
4866

4967
~TableRepMap()
50-
{ /* just let memory leak */
51-
}
52-
53-
// Free all allocated resources. Note that this leaves the TableRepMap
54-
// in an unusable state.
55-
void free_resources()
5668
{
57-
ustring_write_lock_t lock(mutex);
58-
// Destroy TableRep objects FIRST, while the pool/large-alloc memory
59-
// they live in is still valid. Their destructors may read/write the
60-
// surrounding allocation and (on some platforms) the std::string
61-
// subobject owns a separate heap buffer that only gets freed here.
62-
destroy_entries();
63-
entries.clear();
64-
entries.shrink_to_fit();
65-
// Now safe to free the backing buffers.
66-
all_pools.clear();
67-
all_pools.shrink_to_fit();
68-
large_allocs.clear();
69-
large_allocs.shrink_to_fit();
69+
if (OIIO::pvt::oiio_ustring_cleanup) {
70+
// If requested, take the time to properly destroy all the
71+
// entries, and also the unique_ptr arrays all_pools and
72+
// large_allocs will naturally free their contents after this
73+
// destructor body ends.
74+
destroy_entries();
75+
} else {
76+
// If no ustring cleanup was requested, take the fastest possible
77+
// route to exit, just release the pointers and let them leak!
78+
for (auto& p : all_pools)
79+
(void)p.release();
80+
for (auto& p : large_allocs)
81+
(void)p.release();
82+
}
7083
}
7184

7285
size_t get_memory_usage()
@@ -309,12 +322,6 @@ struct UstringTable {
309322
return num;
310323
}
311324

312-
void free_resources()
313-
{
314-
for (auto& bin : bins)
315-
bin.free_resources();
316-
}
317-
318325
# ifdef USTRING_TRACK_NUM_LOOKUPS
319326
size_t get_num_lookups()
320327
{
@@ -744,32 +751,3 @@ ustring::memory()
744751
}
745752

746753
OIIO_NAMESPACE_3_1_END
747-
748-
749-
OIIO_NAMESPACE_BEGIN
750-
namespace pvt {
751-
752-
// If nonzero, the ustring table will be freed at process exit. This is off by
753-
// default because cleanup is unnecessary (the OS reclaims the memory) and can
754-
// add measurable time at exit for large tables. Enable it when using valgrind
755-
// or other leak detectors to suppress false positives. Settable via
756-
// OIIO::attribute("ustring:cleanup",1) or the OIIO_USTRING_CLEANUP
757-
// environment variable.
758-
OIIO_UTIL_API int oiio_ustring_cleanup = Strutil::stoi(
759-
Sysutil::getenv("OIIO_USTRING_CLEANUP"));
760-
761-
// Register an atexit handler once at startup. The handler checks the flag at
762-
// exit time, so it covers both the env-var path (flag set here) and the
763-
// OIIO::attribute() path (flag set later at runtime).
764-
static int ustring_cleanup_atexit_registered = []() {
765-
std::atexit([]() {
766-
if (pvt::oiio_ustring_cleanup) {
767-
v3_1::ustring_table().free_resources();
768-
v3_1::reverse_map().clear();
769-
}
770-
});
771-
return 0;
772-
}();
773-
774-
} // namespace pvt
775-
OIIO_NAMESPACE_END

0 commit comments

Comments
 (0)