diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index 76fbf436..4fbd59b3 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -24,16 +24,16 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() { tcp.setRole(PICloud::TCP::Client); setName("cloud_client"); - is_connected = is_connecting = false; + is_connected = false; CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, disconnected, [this](bool){ - //piCoutObj << "eth.disconnected"; - bool ned = is_connected; - opened_ = is_connected = false; - notifyBuffer(); - if (ned) - disconnected(); +// piCoutObj << "disconnected"; + opened_ = false; + is_connected = false; + cond_connect.notifyOne(); + cond_buff.notifyOne(); + piMSleep(100); }); } @@ -41,10 +41,11 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) PICloudClient::~PICloudClient() { eth.close(); if (is_connected) { - disconnected(); is_connected = false; + disconnected(); + cond_buff.notifyOne(); + cond_connect.notifyOne(); } - notifyBuffer(); close(); stop(); } @@ -62,26 +63,20 @@ void PICloudClient::setKeepConnection(bool on) { bool PICloudClient::openDevice() { - if (isOpened()) return true; +// piCout << "PICloudClient open device" << path(); bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { + mutex_buff.lock(); eth.startThreadedRead(); - is_connecting = true; - PITimeMeasurer tm; - while (tm.elapsed_m() < (int)eth.readTimeout()) { - if (isConnected()) break; - if (!is_connecting) return false; - piMSleep(PIP_MIN_MSLEEP); - } - is_connecting = false; - bool conn_ok = isConnected(); - //piCoutObj << "conn_ok" << conn_ok; + bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout()); +// piCoutObj << "conn_ok" << conn_ok; + mutex_buff.unlock(); if (!conn_ok) { eth.stop(); eth.close(); - //piMSleep(100); + piMSleep(100); } - return conn_ok; + return isConnected(); } else { eth.close(); return false; @@ -90,26 +85,27 @@ bool PICloudClient::openDevice() { bool PICloudClient::closeDevice() { - eth.stop(); PIThread::stop(false); - if (is_connected) + if (is_connected) { + is_connected = false; disconnected(); - is_connected = is_connecting = false; - notifyBuffer(); - waitForFinish(1000); - if (eth.isOpened()) - eth.close(); + cond_buff.notifyOne(); + cond_connect.notifyOne(); + } + eth.stop(); + if (eth.isOpened()) eth.close(); return true; } int PICloudClient::readDevice(void * read_to, int max_size) { - //piCoutObj << "readDevice"; +// piCoutObj << "readDevice"; if (!is_connected) return -1; + int sz = -1; mutex_buff.lock(); cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;}); - int sz = piMini(max_size, buff.size()); - if (sz > 0) { + if (is_connected) { + sz = piMini(max_size, buff.size()); memcpy(read_to, buff.data(), sz); buff.remove(0, sz); } @@ -119,18 +115,11 @@ int PICloudClient::readDevice(void * read_to, int max_size) { int PICloudClient::writeDevice(const void * data, int size) { - //piCoutObj << "writeDevice"; +// piCoutObj << "writeDevice"; return tcp.sendData(PIByteArray(data, size)); } -void PICloudClient::notifyBuffer() { - mutex_buff.lock(); - cond_buff.notifyOne(); - mutex_buff.unlock(); -} - - void PICloudClient::_readed(PIByteArray & ba) { mutex_buff.lock(); PIPair hdr = tcp.parseHeader(ba); @@ -140,13 +129,14 @@ void PICloudClient::_readed(PIByteArray & ba) { if (tcp.parseConnect(ba) == 1) { is_connected = true; connected(); + cond_connect.notifyOne(); } break; case PICloud::TCP::Disconnect: - //piCoutObj << "TCP::Disconnect ..."; + is_connected = false; static_cast(ð)->stop(); eth.close(); - //piCoutObj << "TCP::Disconnect ok"; + disconnected(); break; case PICloud::TCP::Data: if (is_connected) { diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index ab935bb5..0cd50dcd 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -28,7 +28,7 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, connected, [this](){tcp.sendStart();}); CONNECTL(ð, disconnected, [this](bool){ - //piCoutObj << "disconnected"; + piCoutObj << "disconnected"; opened_ = false; piMSleep(100); }); @@ -57,7 +57,7 @@ PIVector PICloudServer::clients() const { bool PICloudServer::openDevice() { - //piCout << "PICloudServer open device" << path(); + piCout << "PICloudServer open device" << path(); bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { eth.startThreadedRead(); @@ -131,21 +131,23 @@ bool PICloudServer::Client::openDevice() { bool PICloudServer::Client::closeDevice() { + PIThread::stop(false); if (is_connected) { server->clientDisconnect(client_id); is_connected = false; - cond_buff.notifyOne(); } + cond_buff.notifyOne(); return true; } int PICloudServer::Client::readDevice(void * read_to, int max_size) { if (!is_connected) return -1; + int sz = -1; mutex_buff.lock(); cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;}); - int sz = piMini(max_size, buff.size()); - if (sz > 0) { + if (is_connected) { + sz = piMini(max_size, buff.size()); memcpy(read_to, buff.data(), sz); buff.remove(0, sz); } @@ -181,7 +183,7 @@ void PICloudServer::_readed(PIByteArray & ba) { if (oc) { tcp.sendDisconnected(id); } else { - //piCoutObj << "new Client" << id; + piCoutObj << "new Client" << id; Client * c = new Client(this, id); CONNECTU(c, deleted, this, clientDeleted); clients_mutex.lock(); @@ -193,7 +195,7 @@ void PICloudServer::_readed(PIByteArray & ba) { } break; case PICloud::TCP::Disconnect: { uint id = tcp.parseDisconnect(ba); - //piCoutObj << "remove Client" << id; + piCoutObj << "remove Client" << id; clients_mutex.lock(); Client * oc = index_clients.value(id, nullptr); clients_mutex.unlock(); diff --git a/libs/main/cloud/picloudclient.h b/libs/main/cloud/picloudclient.h index c0b81779..1ea14883 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -50,14 +50,14 @@ protected: int writeDevice(const void * data, int size); DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;} - void notifyBuffer(); - private: EVENT_HANDLER1(void, _readed, PIByteArray &, data); PIByteArray buff; PIMutex mutex_buff; + PIMutex mutex_connect; PIConditionVariable cond_buff; - std::atomic_bool is_connected, is_connecting; + PIConditionVariable cond_connect; + std::atomic_bool is_connected; }; #endif // PICLOUDCLIENT_H