mirror of https://github.com/PentHertz/srsLTE.git
Implement a function to remove emergency handlers when a signal is raised.
Make PCAP handlers deregister from this list when they are destructed. This avoid the signal handler calling destructed objects under very rare circumstances.
This commit is contained in:
parent
380280b4d0
commit
c9c2d6982f
|
@ -103,7 +103,8 @@ protected:
|
|||
srslog::basic_logger& logger;
|
||||
std::atomic<bool> running = {false};
|
||||
static_blocking_queue<pcap_pdu_t, 1024> queue;
|
||||
uint16_t ue_id = 0;
|
||||
uint16_t ue_id = 0;
|
||||
int emergency_handler_id = -1;
|
||||
|
||||
private:
|
||||
void pack_and_queue(uint8_t* payload,
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<unsigned> 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<unsigned>(id) >= num_handlers) {
|
||||
srsran_assert(0, "Invalid emergency handler id");
|
||||
return;
|
||||
}
|
||||
|
||||
registered_handlers[id].callback.store(nullptr);
|
||||
}
|
||||
|
||||
void execute_emergency_cleanup_handlers()
|
||||
|
|
Loading…
Reference in New Issue