diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index c01661da..b69ab812 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -25,26 +25,35 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) tcp.setRole(PICloud::TCP::Client); setName("cloud_client"); is_connected = false; - CONNECTL(ð, connected, [this](){/*opened_ = true;*/ tcp.sendStart();}); + is_deleted = false; +// setReopenEnabled(false); + CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, disconnected, [this](bool){ - piCoutObj << "disconnected"; + if (is_deleted) return; + //piCoutObj << "eth disconnected"; static_cast(ð)->stop(); - //opened_ = false; + opened_ = false; if (is_connected) disconnected(); internalDisconnect(); - piMSleep(100); + //piCoutObj << "eth disconnected done"; }); } PICloudClient::~PICloudClient() { - piCoutObj << "~PICloudClient()"; + //piCoutObj << "~PICloudClient()"; PIThread::stop(); - eth.close(); + //eth.close(); + if (is_connected) disconnected(); + is_connected = false; + close(); + //piCoutObj << "~PICloudClient() closed"; internalDisconnect(); - //close(); - //stop(false); +// stop(false); + is_deleted = true; + internalDisconnect(); + //piCoutObj << "~PICloudClient() done"; } @@ -60,20 +69,21 @@ void PICloudClient::setKeepConnection(bool on) { bool PICloudClient::openDevice() { - piCout << "PICloudClient open device" << path(); + //piCoutObj << "open";// << path(); bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { mutex_connect.lock(); eth.startThreadedRead(); - piCoutObj << "connecting..."; + //piCoutObj << "connecting..."; bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout()); - piCoutObj << "conn_ok" << conn_ok; + //piCoutObj << "conn_ok" << conn_ok << is_connected; + mutex_connect.unlock(); if (!conn_ok) { + mutex_connect.lock(); eth.stop(); eth.close(); - piMSleep(100); + mutex_connect.unlock(); } - mutex_connect.unlock(); return is_connected; } else { //eth.close(); @@ -83,7 +93,7 @@ bool PICloudClient::openDevice() { bool PICloudClient::closeDevice() { - PIThread::stop(false); + //PIThread::stop(); if (is_connected) { internalDisconnect(); } @@ -94,8 +104,9 @@ bool PICloudClient::closeDevice() { int PICloudClient::readDevice(void * read_to, int max_size) { -// piCoutObj << "readDevice"; - if (!is_connected) return -1; + if (is_deleted) return -1; + //piCoutObj << "readDevice"; + if (!is_connected && eth.isClosed()) openDevice(); int sz = -1; mutex_buff.lock(); cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;}); @@ -105,11 +116,14 @@ int PICloudClient::readDevice(void * read_to, int max_size) { buff.remove(0, sz); } mutex_buff.unlock(); + if (!is_connected) opened_ = false; + //piCoutObj << "readDevice done" << sz; return sz; } int PICloudClient::writeDevice(const void * data, int size) { + if (is_deleted) return -1; // piCoutObj << "writeDevice"; return tcp.sendData(PIByteArray(data, size)); } @@ -123,24 +137,30 @@ void PICloudClient::internalDisconnect() { void PICloudClient::_readed(PIByteArray & ba) { - mutex_buff.lock(); + if (is_deleted) return; + //piCoutObj << "_readed"; PIPair hdr = tcp.parseHeader(ba); if (hdr.second == tcp.role()) { switch (hdr.first) { case PICloud::TCP::Connect: if (tcp.parseConnect(ba) == 1) { + mutex_connect.lock(); is_connected = true; connected(); + mutex_connect.unlock(); cond_connect.notifyOne(); } break; case PICloud::TCP::Disconnect: static_cast(ð)->stop(); + opened_ = false; eth.close(); break; case PICloud::TCP::Data: if (is_connected) { + mutex_buff.lock(); buff.append(ba); + mutex_buff.unlock(); cond_buff.notifyOne(); } break; @@ -149,7 +169,7 @@ void PICloudClient::_readed(PIByteArray & ba) { } //piCoutObj << "readed" << ba.toHex(); } - mutex_buff.unlock(); while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad + //piCoutObj << "_readed done"; } diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 0513772d..ad7500f4 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -26,11 +26,12 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) tcp.setServerName(server_name); setName("cloud_server__" + server_name); CONNECTU(&streampacker, packetReceiveEvent, this, _readed); - CONNECTL(ð, connected, [this](){tcp.sendStart();}); + CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); CONNECTL(ð, disconnected, [this](bool){ - piCoutObj << "disconnected"; + //piCoutObj << "disconnected"; static_cast(ð)->stop(); opened_ = false; + ping_timer.stop(false); piMSleep(100); }); CONNECTL(&ping_timer, tickEvent, [this] (void *, int){ @@ -58,14 +59,14 @@ 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(); ping_timer.start(5000); return true; } - ping_timer.stop(); + ping_timer.stop(false); eth.close(); return false; } @@ -73,6 +74,7 @@ bool PICloudServer::openDevice() { bool PICloudServer::closeDevice() { eth.stop(); + ping_timer.stop(false); clients_mutex.lock(); for (auto c : clients_) { c->close(); @@ -88,7 +90,8 @@ bool PICloudServer::closeDevice() { int PICloudServer::readDevice(void * read_to, int max_size) { //piCoutObj << "readDevice"; - piMSleep(eth.readTimeout()); + if (!opened_) openDevice(); + else piMSleep(eth.readTimeout()); return -1; } @@ -184,7 +187,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(); @@ -196,7 +199,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 49f7456b..cc944b2b 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -60,6 +60,7 @@ private: PIConditionVariable cond_buff; PIConditionVariable cond_connect; std::atomic_bool is_connected; + std::atomic_bool is_deleted; }; #endif // PICLOUDCLIENT_H diff --git a/libs/main/io_devices/piiodevice.cpp b/libs/main/io_devices/piiodevice.cpp index 6036a7a5..482e0367 100644 --- a/libs/main/io_devices/piiodevice.cpp +++ b/libs/main/io_devices/piiodevice.cpp @@ -239,7 +239,7 @@ void PIIODevice::check_start(void * data, int delim) { //cout << "check " << tread_started_ << endl; if (open()) { thread_started_ = true; - timer.stop(); + timer.stop(false); } } diff --git a/main.cpp b/main.cpp index 2d847deb..764f7dd0 100644 --- a/main.cpp +++ b/main.cpp @@ -32,8 +32,8 @@ int main(int argc, char * argv[]) { piCout << "[Client] data:" << str; if (str == "ping_S") c.write(PIString("pong_S").toByteArray()); })); - CONNECTL(&c, connected, ([&](){piCout << "connected";})); - CONNECTL(&c, disconnected, ([&](){piCout << "disconnected";})); + CONNECTL(&c, connected, ([](){piCout << "connected";})); + CONNECTL(&c, disconnected, ([](){piCout << "disconnected";})); CONNECTL(&s, newConnection, ([&](PICloudServer::Client * cl){ piCout << "[Server] new client:" << cl; clients << cl;