Rust equivalent of C++ threadsafe singleton internally linked that is dropped


I have some code that works in C++ and I try to translate it to Rust.

The C++ code do the following:

  1. Provide a class called StringID that is a wrapper on an int.
  2. Constructor of StringID take a string as parameter that is hashed and inserted in a memoy bucket list.
  3. The memory bucket list is similar to a thread safe singleton custom hash map with internal linkage ( Not visible outside the translation unit ).
  4. When the program exit, buckets are freed because C++ call destructor on static variable.
  5. User of StringID don't even know about the bucket and allocation management behind the scene.

The point here is that Rust don't call drop on static variable so I can't just use a static buckets: BucketManagement.... variable because it will not be dropped.

I would like to know, what is the pattern in Rust that is commonly used to provide the same behaviour?
I want to provide a interface to the user like let var = StringID::new("MyString") or static var :StringID = StringID::new("MyString") even const StringID::new("MyString"), then I expect the memory of buckets to be freed when the program is stopped.

Thank's a lot for any help, advise... :slight_smile:

What kind of resource does this singleton hold (aside from memory)? If there's none, then that's OK to just leave it undropped - memory will be reclaimed on program exit anyway.


The singleton manage a list of buckets that contains raw bytes (The string values). There is nothing dangerous here. But leaving the fact that these are only bits, how to do if, for example, it is about access to open files or other resources which must be freed...
I know I can let the OS reclaim the memory, but I don't want to rely on the OS to free it. This pattern is commun in existing C++ code base and don't manage only raw bytes.

If your process exits, and unless the OS has a bug, resources will be cleaned up completely. It doesn't really matter if static destructors are run or not.

If you want precise control over lifetimes, then don't use globals. Create a local variable and pass it to functions that require it.

1 Like

Destructors may call close() which calls the OS. Even if you never free the OS resources like file handles and sockets you're relying on the OS to acquire and correctly handle them. You can directly talk to the block decices with NVMe or SATA protocol over the CPU buses if you're trying to write your own OS which definitely possible in Rust. Besides that, there's nothing much to do if you don't trust the OS.


I got it,

Thank you for all.