mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-07-24 15:27:41 +08:00
fix(px4_daemon): fix startup stdout TLS race
Create the server thread-local stdout key before marking the daemon as running, preventing early startup logs from using an invalid FILE pointer.
This commit is contained in:
committed by
Eric Katzfey
parent
00f436698b
commit
cbe8680a66
@@ -66,17 +66,34 @@ Server::Server(int instance_id)
|
||||
: _mutex(PTHREAD_MUTEX_INITIALIZER),
|
||||
_instance_id(instance_id)
|
||||
{
|
||||
int ret = pthread_key_create(&_key, _pthread_key_destructor);
|
||||
|
||||
if (ret != 0) {
|
||||
PX4_ERR("failed to create pthread key");
|
||||
|
||||
} else {
|
||||
_key_valid = true;
|
||||
}
|
||||
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
_instance = nullptr;
|
||||
|
||||
if (_key_valid) {
|
||||
pthread_key_delete(_key);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Server::start()
|
||||
{
|
||||
if (!_key_valid) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string sock_path = get_socket_path(_instance_id);
|
||||
|
||||
// Delete socket in case it exists already.
|
||||
@@ -129,13 +146,6 @@ void Server::_pthread_key_destructor(void *arg)
|
||||
void
|
||||
Server::_server_main()
|
||||
{
|
||||
int ret = pthread_key_create(&_key, _pthread_key_destructor);
|
||||
|
||||
if (ret != 0) {
|
||||
PX4_ERR("failed to create pthread key");
|
||||
return;
|
||||
}
|
||||
|
||||
// The list of file descriptors to watch.
|
||||
std::vector<pollfd> poll_fds;
|
||||
|
||||
@@ -182,7 +192,7 @@ Server::_server_main()
|
||||
|
||||
// Start a new thread to handle the client.
|
||||
pthread_t *thread = &_fd_to_thread[client];
|
||||
ret = pthread_create(thread, nullptr, Server::_handle_client, thread_stdout);
|
||||
int ret = pthread_create(thread, nullptr, Server::_handle_client, thread_stdout);
|
||||
|
||||
if (ret != 0) {
|
||||
PX4_ERR("could not start pthread (%i)", ret);
|
||||
|
||||
@@ -89,6 +89,12 @@ public:
|
||||
{
|
||||
return _instance->_key;
|
||||
}
|
||||
|
||||
static bool has_pthread_key()
|
||||
{
|
||||
return _instance != nullptr && _instance->_key_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
static void *_server_main_trampoline(void *arg);
|
||||
void _server_main();
|
||||
@@ -111,7 +117,8 @@ private:
|
||||
std::map<int, pthread_t> _fd_to_thread;
|
||||
pthread_mutex_t _mutex; ///< Protects _fd_to_thread.
|
||||
|
||||
pthread_key_t _key;
|
||||
pthread_key_t _key{};
|
||||
bool _key_valid{false};
|
||||
|
||||
int _instance_id; ///< instance ID for running multiple instances of the px4 server
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ using namespace px4_daemon;
|
||||
FILE *get_stdout(bool *isatty_)
|
||||
{
|
||||
// If the server is not running, we are not in a thread that has been started
|
||||
if (!Server::is_running()) {
|
||||
if (!Server::is_running() || !Server::has_pthread_key()) {
|
||||
if (isatty_) { *isatty_ = isatty(1); }
|
||||
|
||||
return stdout;
|
||||
|
||||
Reference in New Issue
Block a user