diff --git a/libs/main/core/piwaitevent_p.cpp b/libs/main/core/piwaitevent_p.cpp index d576ba31..954aa870 100644 --- a/libs/main/core/piwaitevent_p.cpp +++ b/libs/main/core/piwaitevent_p.cpp @@ -28,7 +28,6 @@ # include # include #endif -#include "piincludes_p.h" #include "pistring.h" @@ -45,7 +44,7 @@ void PIWaitEvent::create() { piCout << "Error with CreateEventA:" << errorString(); } #else - for (int i = 0; i < sizeof(fds); ++i) memset(&(fds[i]), 0, sizeof(fds[i])); + for (int i = 0; i < 3; ++i) memset(&(fds[i]), 0, sizeof(fds[i])); if (::pipe(pipe_fd) < 0) { piCout << "Error with pipe:" << errorString(); } else { @@ -62,7 +61,7 @@ void PIWaitEvent::destroy() { event = NULL; } #else - for (int i = 0; i < sizeof(pipe_fd); ++i) { + for (int i = 0; i < 2; ++i) { if (pipe_fd[i] != 0) { ::close(pipe_fd[i]); pipe_fd[i] = 0; @@ -82,7 +81,7 @@ bool PIWaitEvent::wait(int fd, CheckRole role) { if (fd == -1) return false; int nfds = piMaxi(pipe_fd[ReadEnd], fd) + 1; int fd_index = role; - for (int i = 0; i < sizeof(fds); ++i) FD_ZERO(&(fds[i])); + for (int i = 0; i < 3; ++i) FD_ZERO(&(fds[i])); FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead])); FD_SET(fd, &(fds[CheckExeption])); if (fd_index != CheckExeption) FD_SET(fd, &(fds[fd_index])); @@ -116,5 +115,9 @@ bool PIWaitEvent::isCreate() const { void * PIWaitEvent::getEvent() const { +#ifdef WINDOWS return event; +#else + return nullptr; +#endif } diff --git a/libs/main/core/piwaitevent_p.h b/libs/main/core/piwaitevent_p.h index e0f18299..a4395eaf 100644 --- a/libs/main/core/piwaitevent_p.h +++ b/libs/main/core/piwaitevent_p.h @@ -35,19 +35,17 @@ class PIWaitEvent { public: ~PIWaitEvent(); - void create(); - void destroy(); - enum CheckRole { // UNIX only CheckRead, CheckWrite, CheckExeption }; - bool wait(int fd = -1, CheckRole role = CheckRead); + void create(); + void destroy(); + bool wait(int fd = -1, CheckRole role = CheckRead); void interrupt(); bool isCreate() const; - void * getEvent() const; // WINDOWS only private: diff --git a/libs/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp index 66381091..7f42774e 100644 --- a/libs/main/io_devices/pican.cpp +++ b/libs/main/io_devices/pican.cpp @@ -18,7 +18,7 @@ */ #include "pican.h" #include "pipropertystorage.h" -#include "piincludes_p.h" +#include "piwaitevent_p.h" #if !defined(WINDOWS) && !defined(MAC_OS) && !defined(MICRO_PIP) # define PIP_CAN #endif @@ -39,17 +39,24 @@ REGISTER_DEVICE(PICAN) +PRIVATE_DEFINITION_START(PICAN) + PIWaitEvent event; +PRIVATE_DEFINITION_END(PICAN) + + PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) { setThreadedReadBufferSize(256); setPath(path); can_id = 0; sock = 0; + PRIVATE->event.create(); } PICAN::~PICAN() { - stop(); + stopAndWait(); close(); + PRIVATE->event.destroy(); } @@ -92,6 +99,7 @@ bool PICAN::openDevice() { bool PICAN::closeDevice() { #ifdef PIP_CAN + interrupt(); if (sock > 0) ::close(sock); #endif return true; @@ -103,9 +111,8 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) { //piCout << "PICAN read"; can_frame frame; ssize_t ret = 0; - reading_now = true; - ret = ::read(sock, &frame, sizeof(can_frame)); - reading_now = false; + if (PRIVATE->event.wait(sock)) + ret = ::read(sock, &frame, sizeof(can_frame)); if (ret < 0) {/*piCoutObj << "Error while read CAN frame " << ret;*/ return -1;} //piCoutObj << "receive CAN frame Id =" << frame.can_id; memcpy(read_to, frame.data, piMini(frame.can_dlc, max_size)); @@ -148,6 +155,11 @@ int PICAN::readedCANID() const { } +void PICAN::interrupt() { + PRIVATE->event.interrupt(); +} + + PIString PICAN::constructFullPathDevice() const { PIString ret; ret += path() + ":" + PIString::fromNumber(CANID(), 16); diff --git a/libs/main/io_devices/pican.h b/libs/main/io_devices/pican.h index 8afab4d7..199ccf5f 100644 --- a/libs/main/io_devices/pican.h +++ b/libs/main/io_devices/pican.h @@ -39,6 +39,7 @@ public: void setCANID(int id); int CANID() const; int readedCANID() const; + void interrupt() override; protected: bool openDevice() override; @@ -52,6 +53,7 @@ protected: DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;} private: + PRIVATE_DECLARATION(PIP_EXPORT) int sock; int can_id, readed_id; };