mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-07-07 05:42:06 +08:00
9504037aa7
01942b89 add TODO b74a456a don't hardcode the lists ed5a4bf5 add face stds 396a2bb5 add can error counter to controlsState c6b5c73b Switch default to msgq (#21) a457ffa0 Fix indentation in readme.md a1fc8c75 explicitly mention Python for syntax colouring (#20) 19e23931 Fix expected for cameraOdometry and liveCalibration e7d2f978 Add radar comm issue error db64cd43 Reserve safety #21 for VAG PQ35/PQ46/NMS (#19) 79d638d5 separate honda safety models between Bosch Giraffe and Bosch Nidec 2614a650 better name b6b84cda add longitudinal 78f5934a Add canRxErrs to health 67588993 qlog liveCalibration df80b870 add more stuff to fw log in CarParams a87805ad fix doxs 4746b208 got doxed 21cf3f55 build on mac 31ac47c2 Add carUnrecognized event git-subtree-dir: cereal git-subtree-split: 01942b890d7acf19aecc09432fe5048ba21c0fc9
196 lines
3.5 KiB
C++
196 lines
3.5 KiB
C++
#include <cassert>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <cstdlib>
|
|
#include <csignal>
|
|
#include <cerrno>
|
|
|
|
|
|
#include "impl_msgq.hpp"
|
|
|
|
volatile sig_atomic_t msgq_do_exit = 0;
|
|
|
|
void sig_handler(int signal) {
|
|
assert(signal == SIGINT || signal == SIGTERM);
|
|
msgq_do_exit = 1;
|
|
}
|
|
|
|
|
|
MSGQContext::MSGQContext() {
|
|
}
|
|
|
|
MSGQContext::~MSGQContext() {
|
|
}
|
|
|
|
void MSGQMessage::init(size_t sz) {
|
|
size = sz;
|
|
data = new char[size];
|
|
}
|
|
|
|
void MSGQMessage::init(char * d, size_t sz) {
|
|
size = sz;
|
|
data = new char[size];
|
|
memcpy(data, d, size);
|
|
}
|
|
|
|
void MSGQMessage::takeOwnership(char * d, size_t sz) {
|
|
size = sz;
|
|
data = d;
|
|
}
|
|
|
|
void MSGQMessage::close() {
|
|
if (size > 0){
|
|
delete[] data;
|
|
}
|
|
size = 0;
|
|
}
|
|
|
|
MSGQMessage::~MSGQMessage() {
|
|
this->close();
|
|
}
|
|
|
|
|
|
int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
|
|
assert(context);
|
|
assert(address == "127.0.0.1");
|
|
|
|
q = new msgq_queue_t;
|
|
int r = msgq_new_queue(q, endpoint.c_str(), DEFAULT_SEGMENT_SIZE);
|
|
if (r != 0){
|
|
return r;
|
|
}
|
|
|
|
msgq_init_subscriber(q);
|
|
|
|
if (conflate){
|
|
q->read_conflate = true;
|
|
}
|
|
|
|
timeout = -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Message * MSGQSubSocket::receive(bool non_blocking){
|
|
msgq_do_exit = 0;
|
|
|
|
void (*prev_handler_sigint)(int);
|
|
void (*prev_handler_sigterm)(int);
|
|
if (!non_blocking){
|
|
prev_handler_sigint = std::signal(SIGINT, sig_handler);
|
|
prev_handler_sigterm = std::signal(SIGTERM, sig_handler);
|
|
}
|
|
|
|
msgq_msg_t msg;
|
|
|
|
MSGQMessage *r = NULL;
|
|
|
|
int rc = msgq_msg_recv(&msg, q);
|
|
|
|
// Hack to implement blocking read with a poller. Don't use this
|
|
while (!non_blocking && rc == 0 && msgq_do_exit == 0){
|
|
msgq_pollitem_t items[1];
|
|
items[0].q = q;
|
|
|
|
int t = (timeout != -1) ? timeout : 100;
|
|
|
|
int n = msgq_poll(items, 1, t);
|
|
rc = msgq_msg_recv(&msg, q);
|
|
|
|
// The poll indicated a message was ready, but the receive failed. Try again
|
|
if (n == 1 && rc == 0){
|
|
continue;
|
|
}
|
|
|
|
if (timeout != -1){
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (!non_blocking){
|
|
std::signal(SIGINT, prev_handler_sigint);
|
|
std::signal(SIGTERM, prev_handler_sigterm);
|
|
}
|
|
|
|
errno = msgq_do_exit ? EINTR : 0;
|
|
|
|
if (rc > 0){
|
|
if (msgq_do_exit){
|
|
msgq_msg_close(&msg); // Free unused message on exit
|
|
} else {
|
|
r = new MSGQMessage;
|
|
r->takeOwnership(msg.data, msg.size);
|
|
}
|
|
}
|
|
|
|
return (Message*)r;
|
|
}
|
|
|
|
void MSGQSubSocket::setTimeout(int t){
|
|
timeout = t;
|
|
}
|
|
|
|
MSGQSubSocket::~MSGQSubSocket(){
|
|
if (q != NULL){
|
|
msgq_close_queue(q);
|
|
delete q;
|
|
}
|
|
}
|
|
|
|
int MSGQPubSocket::connect(Context *context, std::string endpoint){
|
|
assert(context);
|
|
|
|
q = new msgq_queue_t;
|
|
msgq_new_queue(q, endpoint.c_str(), DEFAULT_SEGMENT_SIZE);
|
|
msgq_init_publisher(q);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MSGQPubSocket::sendMessage(Message *message){
|
|
msgq_msg_t msg;
|
|
msg.data = message->getData();
|
|
msg.size = message->getSize();
|
|
|
|
return msgq_msg_send(&msg, q);
|
|
}
|
|
|
|
int MSGQPubSocket::send(char *data, size_t size){
|
|
msgq_msg_t msg;
|
|
msg.data = data;
|
|
msg.size = size;
|
|
|
|
return msgq_msg_send(&msg, q);
|
|
}
|
|
|
|
MSGQPubSocket::~MSGQPubSocket(){
|
|
if (q != NULL){
|
|
msgq_close_queue(q);
|
|
delete q;
|
|
}
|
|
}
|
|
|
|
|
|
void MSGQPoller::registerSocket(SubSocket * socket){
|
|
assert(num_polls + 1 < MAX_POLLERS);
|
|
polls[num_polls].q = (msgq_queue_t*)socket->getRawSocket();
|
|
|
|
sockets.push_back(socket);
|
|
num_polls++;
|
|
}
|
|
|
|
std::vector<SubSocket*> MSGQPoller::poll(int timeout){
|
|
std::vector<SubSocket*> r;
|
|
|
|
msgq_poll(polls, num_polls, timeout);
|
|
for (size_t i = 0; i < num_polls; i++){
|
|
if (polls[i].revents){
|
|
r.push_back(sockets[i]);
|
|
}
|
|
}
|
|
|
|
return r;
|
|
}
|