diff --git a/lib/include/srsran/common/mac_pcap_base.h b/lib/include/srsran/common/mac_pcap_base.h index f9394bfbd..c446c747e 100644 --- a/lib/include/srsran/common/mac_pcap_base.h +++ b/lib/include/srsran/common/mac_pcap_base.h @@ -103,7 +103,8 @@ protected: srslog::basic_logger& logger; std::atomic running = {false}; static_blocking_queue queue; - uint16_t ue_id = 0; + uint16_t ue_id = 0; + int emergency_handler_id = -1; private: void pack_and_queue(uint8_t* payload, diff --git a/lib/include/srsran/common/nas_pcap.h b/lib/include/srsran/common/nas_pcap.h index f93c17a27..34a13bea9 100644 --- a/lib/include/srsran/common/nas_pcap.h +++ b/lib/include/srsran/common/nas_pcap.h @@ -23,16 +23,18 @@ class nas_pcap { public: nas_pcap(); - void enable(); + ~nas_pcap(); + void enable(); uint32_t open(std::string filename_, uint32_t ue_id = 0, srsran_rat_t rat_type = srsran_rat_t::lte); - void close(); - void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); + void close(); + void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); private: bool enable_write = false; std::string filename; - FILE* pcap_file = nullptr; - uint32_t ue_id = 0; + FILE* pcap_file = nullptr; + uint32_t ue_id = 0; + int emergency_handler_id = -1; void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes); }; diff --git a/lib/include/srsran/common/ngap_pcap.h b/lib/include/srsran/common/ngap_pcap.h index e56c0ff6f..bbfc8f6df 100644 --- a/lib/include/srsran/common/ngap_pcap.h +++ b/lib/include/srsran/common/ngap_pcap.h @@ -22,7 +22,7 @@ class ngap_pcap { public: ngap_pcap(); - ~ngap_pcap() = default; + ~ngap_pcap(); ngap_pcap(const ngap_pcap& other) = delete; ngap_pcap& operator=(const ngap_pcap& other) = delete; ngap_pcap(ngap_pcap&& other) = delete; @@ -36,7 +36,8 @@ public: private: bool enable_write = false; std::string filename; - FILE* pcap_file = nullptr; + FILE* pcap_file = nullptr; + int emergency_handler_id = -1; }; } // namespace srsran diff --git a/lib/include/srsran/common/s1ap_pcap.h b/lib/include/srsran/common/s1ap_pcap.h index 0e9cae421..459790b8f 100644 --- a/lib/include/srsran/common/s1ap_pcap.h +++ b/lib/include/srsran/common/s1ap_pcap.h @@ -22,6 +22,7 @@ class s1ap_pcap { public: s1ap_pcap(); + ~s1ap_pcap(); s1ap_pcap(const s1ap_pcap& other) = delete; s1ap_pcap& operator=(const s1ap_pcap& other) = delete; s1ap_pcap(s1ap_pcap&& other) = delete; @@ -35,7 +36,8 @@ public: private: bool enable_write = false; std::string filename; - FILE* pcap_file = nullptr; + FILE* pcap_file = nullptr; + int emergency_handler_id = -1; }; } // namespace srsran diff --git a/lib/include/srsran/support/emergency_handlers.h b/lib/include/srsran/support/emergency_handlers.h index 818f1a211..6fe5c2fba 100644 --- a/lib/include/srsran/support/emergency_handlers.h +++ b/lib/include/srsran/support/emergency_handlers.h @@ -17,7 +17,11 @@ using emergency_cleanup_callback = void (*)(void*); // Add a cleanup function to be called when a kill signal is about to be delivered to the process. The handler may // optionally pass a pointer to identify what instance of the handler is being called. -void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data); +// Returns the id of the handler as a positive value, otherwise returns -1 on error. +int add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data); + +// Removes the emergency handler with the specified id. +void remove_emergency_cleanup_handler(int id); // Executes all registered emergency cleanup handlers. void execute_emergency_cleanup_handlers(); diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index 2a12110d7..32c9902b5 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -26,10 +26,15 @@ static void emergency_cleanup_handler(void* data) mac_pcap_base::mac_pcap_base() : logger(srslog::fetch_basic_logger("MAC")), thread("PCAP_WRITER_MAC") { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); } -mac_pcap_base::~mac_pcap_base() {} +mac_pcap_base::~mac_pcap_base() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } +} void mac_pcap_base::enable(bool enable_) { diff --git a/lib/src/common/nas_pcap.cc b/lib/src/common/nas_pcap.cc index 1011d0d12..7a6f482ae 100644 --- a/lib/src/common/nas_pcap.cc +++ b/lib/src/common/nas_pcap.cc @@ -26,7 +26,14 @@ static void emergency_cleanup_handler(void* data) nas_pcap::nas_pcap() { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +nas_pcap::~nas_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } } void nas_pcap::enable() diff --git a/lib/src/common/ngap_pcap.cc b/lib/src/common/ngap_pcap.cc index 34ce35d2d..0174aeb1e 100644 --- a/lib/src/common/ngap_pcap.cc +++ b/lib/src/common/ngap_pcap.cc @@ -26,7 +26,14 @@ static void emergency_cleanup_handler(void* data) ngap_pcap::ngap_pcap() { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +ngap_pcap::~ngap_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } } void ngap_pcap::enable() diff --git a/lib/src/common/s1ap_pcap.cc b/lib/src/common/s1ap_pcap.cc index 3909673d4..b52221419 100644 --- a/lib/src/common/s1ap_pcap.cc +++ b/lib/src/common/s1ap_pcap.cc @@ -26,7 +26,14 @@ static void emergency_cleanup_handler(void* data) s1ap_pcap::s1ap_pcap() { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +s1ap_pcap::~s1ap_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } } void s1ap_pcap::enable() diff --git a/lib/src/support/emergency_handlers.cc b/lib/src/support/emergency_handlers.cc index b4e2cdc9a..fb170f848 100644 --- a/lib/src/support/emergency_handlers.cc +++ b/lib/src/support/emergency_handlers.cc @@ -11,6 +11,7 @@ */ #include "srsran/support/emergency_handlers.h" +#include "srsran/config.h" #include "srsran/support/srsran_assert.h" namespace { @@ -29,7 +30,7 @@ static constexpr unsigned max_handlers = 12; static handler_instance registered_handlers[max_handlers]; static std::atomic num_handlers; -void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data) +int add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data) { // Reserve a slot in the array. auto pos = num_handlers.fetch_add(1); @@ -37,13 +38,25 @@ void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* da // Check if we have space in the array. if (pos >= max_handlers) { srsran_assert(0, "Exceeded the emergency cleanup handler registered limit"); - return; + return SRSRAN_ERROR; } // Order is important here: write last the callback member as it is used to signal that the handler is valid when // reading the array. registered_handlers[pos].data.store(data); registered_handlers[pos].callback.store(callback); + + return pos; +} + +void remove_emergency_cleanup_handler(int id) +{ + if (id < 0 || static_cast(id) >= num_handlers) { + srsran_assert(0, "Invalid emergency handler id"); + return; + } + + registered_handlers[id].callback.store(nullptr); } void execute_emergency_cleanup_handlers()