небольшая чистка и улучшение кода, попытка исправить picloud

This commit is contained in:
Бычков Андрей
2022-11-07 17:16:27 +03:00
parent 8a5e72c723
commit f08a07cab0
11 changed files with 54 additions and 79 deletions

View File

@@ -45,10 +45,7 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
PICloudClient::~PICloudClient() {
//piCoutObj << "~PICloudClient()";
//softStopThreadedRead();
//eth.close();
//if (is_connected) disconnected();
//close();
stopAndWait();
//piCoutObj << "~PICloudClient() closed";
internalDisconnect();
@@ -71,7 +68,8 @@ void PICloudClient::setKeepConnection(bool on) {
void PICloudClient::interrupt() {
eth.interrupt();
cond_buff.notifyOne();
cond_connect.notifyOne();
}
@@ -87,7 +85,7 @@ bool PICloudClient::openDevice() {
mutex_connect.unlock();
if (!conn_ok) {
mutex_connect.lock();
eth.stop();
eth.stopAndWait();
eth.close();
mutex_connect.unlock();
}
@@ -104,7 +102,7 @@ bool PICloudClient::closeDevice() {
if (is_connected) {
internalDisconnect();
}
eth.stop();
eth.stopAndWait();
eth.close();
return true;
}
@@ -116,11 +114,15 @@ ssize_t PICloudClient::readDevice(void * read_to, ssize_t max_size) {
if (!is_connected && eth.isClosed()) openDevice();
ssize_t sz = -1;
mutex_buff.lock();
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
cond_buff.wait(mutex_buff);
if (is_connected) {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz);
buff.remove(0, sz);
if (buff.isEmpty()) {
sz = 0;
} else {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz);
buff.remove(0, sz);
}
}
mutex_buff.unlock();
if (!is_connected) opened_ = false;
@@ -136,11 +138,6 @@ ssize_t PICloudClient::writeDevice(const void * data, ssize_t size) {
}
void PICloudClient::stopThreadedReadDevice() {
cond_buff.notifyOne();
}
void PICloudClient::internalDisconnect() {
is_connected = false;
cond_buff.notifyOne();

View File

@@ -102,11 +102,6 @@ ssize_t PICloudServer::writeDevice(const void * data, ssize_t max_size) {
}
void PICloudServer::stopThreadedReadDevice() {
}
void PICloudServer::interrupt() {
eth.interrupt();
}
@@ -159,11 +154,15 @@ ssize_t PICloudServer::Client::readDevice(void * read_to, ssize_t max_size) {
if (!is_connected) return -1;
ssize_t sz = -1;
mutex_buff.lock();
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
cond_buff.wait(mutex_buff);
if (is_connected) {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz);
buff.remove(0, sz);
if (buff.isEmpty()) {
sz = 0;
} else {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz);
buff.remove(0, sz);
}
}
mutex_buff.unlock();
return sz;

View File

@@ -54,7 +54,6 @@ protected:
ssize_t readDevice(void * read_to, ssize_t max_size) override;
ssize_t writeDevice(const void * data, ssize_t size) override;
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Reliable;}
void stopThreadedReadDevice() override;
private:
EVENT_HANDLER1(void, _readed, PIByteArray &, data);

View File

@@ -74,7 +74,6 @@ protected:
bool closeDevice() override;
ssize_t readDevice(void * read_to, ssize_t max_size) override;
ssize_t writeDevice(const void * data, ssize_t max_size) override;
void stopThreadedReadDevice() override;
void interrupt() override;
private:

View File

@@ -45,7 +45,7 @@ void PIWaitEvent::create() {
piCout << "Error with CreateEventA:" << errorString();
}
#else
for (int i = 0; i < 3; ++i) memset(&(fds[i]), 0, sizeof(fds[i]));
for (int i = 0; i < sizeof(fds); ++i) memset(&(fds[i]), 0, sizeof(fds[i]));
if (::pipe(pipe_fd) < 0) {
piCout << "Error with pipe:" << errorString();
} else {
@@ -62,7 +62,7 @@ void PIWaitEvent::destroy() {
event = NULL;
}
#else
for (int i = 0; i < 2; ++i) {
for (int i = 0; i < sizeof(pipe_fd); ++i) {
if (pipe_fd[i] != 0) {
::close(pipe_fd[i]);
pipe_fd[i] = 0;
@@ -72,35 +72,24 @@ void PIWaitEvent::destroy() {
}
#ifdef WINDOWS
bool PIWaitEvent::wait() {
#else
bool PIWaitEvent::wait(int fd, PIWaitEvent::SelectRole role) {
#endif
bool PIWaitEvent::wait(int fd, CheckRole role) {
if (!isCreate()) return false;
#ifdef WINDOWS
DWORD ret = WaitForSingleObjectEx(event, INFINITE, TRUE);
ResetEvent(event);
if (ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED) return false;
#else
if (fd == -1) return false;
int nfds = piMaxi(pipe_fd[ReadEnd], fd) + 1;
int fd_index = 0;
switch (role) {
case CheckRead:
fd_index = 0;
break;
case CheckWrite:
fd_index = 1;
break;
}
for (int i = 0; i < 3; ++i) FD_ZERO(&(fds[i]));
FD_SET(pipe_fd[ReadEnd], &(fds[0]));
FD_SET(fd, &(fds[2]));
FD_SET(fd, &(fds[fd_index]));
::select(nfds, &(fds[0]), &(fds[1]), &(fds[2]), nullptr);
int fd_index = role;
for (int i = 0; i < sizeof(fds); ++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]));
::select(nfds, &(fds[CheckRead]), &(fds[CheckWrite]), &(fds[CheckExeption]), nullptr);
int buf = 0;
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0);
if (FD_ISSET(fd, &(fds[2]))) return false;
if (FD_ISSET(fd, &(fds[CheckExeption]))) return false;
return FD_ISSET(fd, &(fds[fd_index]));
#endif
return true;
@@ -124,3 +113,8 @@ bool PIWaitEvent::isCreate() const {
return pipe_fd[ReadEnd] != 0;
#endif
}
void * PIWaitEvent::getEvent() const {
return event;
}

View File

@@ -37,22 +37,23 @@ public:
void create();
void destroy();
#ifdef WINDOWS
bool wait();
#else
enum SelectRole {
enum CheckRole { // UNIX only
CheckRead,
CheckWrite
CheckWrite,
CheckExeption
};
bool wait(int fd, SelectRole role = CheckRead);
#endif
bool wait(int fd = -1, CheckRole role = CheckRead);
void interrupt();
bool isCreate() const;
#ifdef WINDOWS
HANDLE event = NULL;
#else
void * getEvent() const; // WINDOWS only
private:
#ifdef WINDOWS
void * event = nullptr;
#else
int pipe_fd[2] = {0, 0};
fd_set fds[3];
enum {

View File

@@ -977,14 +977,14 @@ bool PIEthernet::connectTCP() {
#ifdef WINDOWS
long PIEthernet::waitForEvent(long mask) {
if (!PRIVATE->event.isCreate() || sock < 0) return 0;
WSAEventSelect(sock, PRIVATE->event.event, mask);
WSAEventSelect(sock, PRIVATE->event.getEvent(), mask);
if (PRIVATE->event.wait()) {
//DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
//piCout << "wait result" << wr;
//if (wr == WSA_WAIT_EVENT_0) {
WSANETWORKEVENTS events;
memset(&events, 0, sizeof(events));
WSAEnumNetworkEvents(sock, PRIVATE->event.event, &events);
WSAEnumNetworkEvents(sock, PRIVATE->event.getEvent(), &events);
//piCout << "wait result" << events.lNetworkEvents;
return events.lNetworkEvents;
}

View File

@@ -439,9 +439,7 @@ PIByteArray PIFile::get() {
ssize_t PIFile::readDevice(void * read_to, ssize_t max_size) {
if (!canRead() || PRIVATE->fd == 0) return -1;
reading_now = true;
ssize_t ret = fread(read_to, 1, max_size, PRIVATE->fd);
reading_now = false;
return ret;
}

View File

@@ -217,11 +217,8 @@ void PIIODevice::stopThreadedRead() {
read_thread.stop();
if (!destroying) {
interrupt();
stopThreadedReadDevice();
}
if (reading_now) {
read_thread.terminate();
reading_now = false;
} else {
piCoutObj << "Error: Device is running after destructor!";
}
#endif
}
@@ -307,7 +304,6 @@ ssize_t PIIODevice::write(const void * data, ssize_t max_size) {
void PIIODevice::_init() {
reading_now = false;
setOptions(0);
setReopenEnabled(true);
setReopenTimeout(1000);

View File

@@ -499,10 +499,6 @@ protected:
//! \~russian Метод вызывается после каждого успешного потокового чтения, по умолчанию вызывает callback "ret_func_"
virtual bool threadedRead(const uchar * readed, ssize_t size);
//! \~english Function executed after PIThread::stop() and PIThread::interrupt() of read thread
//! \~russian Метод вызывается после PIThread::stop() и PIThread::interrupt() потока чтения
virtual void stopThreadedReadDevice() {}
//! \~english Reimplement to construct full unambiguous string, describes this device.
//! Default implementation returns \a path()
//! \~russian Переопределите для создания строки полного описания устройства.
@@ -549,10 +545,6 @@ protected:
bool opened_ = false;
void * ret_data_ = nullptr;
//! \~english Set this flag while blocking operations
//! \~russian Устанавливайте этот флаг во время блокирующих операций
std::atomic_bool reading_now;
private:
EVENT_HANDLER(void, read_func);
EVENT_HANDLER(void, write_func);

View File

@@ -814,7 +814,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
if (sending) return -1;
//piCoutObj << "read ..." << PRIVATE->hCom;
memset(&(PRIVATE->overlap), 0, sizeof(PRIVATE->overlap));
PRIVATE->overlap.hEvent = PRIVATE->event.event;
PRIVATE->overlap.hEvent = PRIVATE->event.getEvent();
ReadFile(PRIVATE->hCom, read_to, max_size, NULL, &(PRIVATE->overlap));
PRIVATE->readed = 0;
if (PRIVATE->event.wait()) {
@@ -860,7 +860,7 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
//piCoutObj << "send ..." << max_size;// << ": " << PIString((char*)data, max_size);
sending = true;
memset(&(PRIVATE->overlap_write), 0, sizeof(PRIVATE->overlap_write));
PRIVATE->overlap_write.hEvent = PRIVATE->event_write.event;
PRIVATE->overlap_write.hEvent = PRIVATE->event_write.getEvent();
WriteFile(PRIVATE->hCom, data, max_size, NULL, &(PRIVATE->overlap_write));
if (PRIVATE->event_write.wait()) {
GetOverlappedResult(PRIVATE->hCom, &(PRIVATE->overlap_write), &wrote, FALSE);