mirror of
https://gitlab.com/prpl-foundation/prplmesh/prplMesh.git
synced 2025-12-20 01:21:22 +08:00
AmbiorixConnection::read_signal and the lambda in AmbiorixImpl::init_signal_loop may race when multiple signals with the same path arrive at the same time, because the underlying amxp_signal_read does not treat the expression evaluation procedure as a critical area, which free/alloc memory to the expression binary tree when evaluate fields. this fix adds a mutex to avoid amxp_signal_read race condition, the cost is performance. before this commit, most signals which have different paths can race without any consequence, only those have the same path possiblly trigger SIGSEGV. after this commit, all signals handling have to be synchronized, even if they do not share the same path. Signed-off-by: Lu Dai <lu.dai@mind.be>
76 lines
2.1 KiB
C++
76 lines
2.1 KiB
C++
/* SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
*
|
|
* SPDX-FileCopyrightText: 2019-2020 the prplMesh contributors (see AUTHORS.md)
|
|
*
|
|
* This code is subject to the terms of the BSD+Patent license.
|
|
* See LICENSE file for more details.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <iomanip>
|
|
#include <limits.h>
|
|
#include <mapf/common/logger.h>
|
|
#include <mapf/common/utils.h>
|
|
#include <sstream>
|
|
#include <unistd.h>
|
|
|
|
namespace mapf {
|
|
namespace utils {
|
|
|
|
std::string get_install_path()
|
|
{
|
|
char path_install_file[PATH_MAX + 1];
|
|
std::string path_install_dir;
|
|
|
|
auto len = readlink("/proc/self/exe", path_install_file, sizeof(path_install_file) - 1);
|
|
if (len == -1) {
|
|
return std::string();
|
|
}
|
|
path_install_file[len] = '\0';
|
|
path_install_dir = path_install_file;
|
|
auto end_search = path_install_dir.rfind("/");
|
|
if (end_search == std::string::npos) {
|
|
return std::string();
|
|
}
|
|
end_search = path_install_dir.rfind("/", end_search - 1);
|
|
if (end_search == std::string::npos) {
|
|
return std::string();
|
|
}
|
|
return path_install_dir.substr(0, end_search + 1);
|
|
}
|
|
|
|
std::string dump_buffer(uint8_t *buffer, size_t len)
|
|
{
|
|
std::ostringstream hexdump;
|
|
for (size_t i = 0; i < len; i += 16) {
|
|
for (size_t j = i; j < len && j < i + 16; j++)
|
|
hexdump << std::hex << std::setw(2) << std::setfill('0') << (unsigned)buffer[j] << " ";
|
|
hexdump << std::endl;
|
|
}
|
|
return hexdump.str();
|
|
}
|
|
|
|
void copy_string(char *dst, const char *src, size_t dst_len)
|
|
{
|
|
const char *src_end = std::find(src, src + dst_len, '\0');
|
|
std::copy(src, src_end, dst);
|
|
std::ptrdiff_t src_size = src_end - src;
|
|
std::ptrdiff_t dst_size = dst_len;
|
|
if (src_size < dst_size) {
|
|
dst[src_size] = 0;
|
|
} else {
|
|
dst[dst_size - 1] = 0;
|
|
MAPF_ERR("copy_string() overflow, src string:'" << src << "'"
|
|
<< " dst_size=" << dst_size << std::endl);
|
|
}
|
|
}
|
|
|
|
} // namespace utils
|
|
} // namespace mapf
|
|
|
|
namespace beerocks {
|
|
|
|
std::mutex amxp_signal_read_mutex;
|
|
|
|
} // namespace beerocks
|