3

I know it is not safe for malloc or free to be called, directly or indirectly, from a signal handler.

But, if I can guarantee that at least one shared reference will remain alive, is it then safe to copy-construct and destruct additional shared or weak references, or do I have to roll my own refcounting?

(Yes, I know signal handlers usually shouldn't do much. But I have a good reason this time.)

o11c
  • 15,265
  • 4
  • 50
  • 75

1 Answers1

7

The C++ standard defines the concept of a "plain old function" as follows:

A POF (“plain old function”) is a function that uses only features from [the C/C++] common subset, and that does not directly or indirectly use any function that is not a POF, except that it may use plain lock-free atomic operations.

Furthermore:

The behavior of any function other than a POF used as a signal handler in a C++ program is implementation-defined.

Obviously, C++ class objects are not part of the C/C++ common subset, and therefore using them in a signal handler yields implementation-defined behavior.

Now, many implementations will allow you limited usage of C++ features. If your implementation doesn't permit memory allocations or exceptions, then here's what we know about those smart pointer types.

Then all weak_ptr constructors are explicitly declared noexcept. So they can't throw exceptions. This also means that they're not allowed to allocate memory (since failing to allocate memory would throw an exception). Yes, they could allocate memory and std::terminate if it fails, but that would be exceedingly rude for an implementation to do.

The copy&move constructors of shared_ptr similarly is noexcept, so the same applies. This is also true for the aliasing constructor for shared_ptr.

If you are absolutely certain that at least one shared_ptr will still exist, then destroying a shared_ptr is explicitly stated to not have side effects. Which probably includes memory de-allocations.

Those are the guarantees that the standard library gives you.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982