blocking PIEthernet write works
This commit is contained in:
@@ -418,7 +418,10 @@ bool PIEthernet::closeDevice() {
|
|||||||
closeSocket(sock_s);
|
closeSocket(sock_s);
|
||||||
while (!clients_.isEmpty())
|
while (!clients_.isEmpty())
|
||||||
delete clients_.back();
|
delete clients_.back();
|
||||||
if (ned) disconnected(false);
|
if (ned) {
|
||||||
|
piCoutObj << "Disconnect on close";
|
||||||
|
disconnected(false);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,13 +582,14 @@ bool PIEthernet::connect(bool threaded) {
|
|||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||||
#endif
|
#endif
|
||||||
|
connecting_ = true;
|
||||||
connected_ = connectTCP();
|
connected_ = connectTCP();
|
||||||
|
connecting_ = false;
|
||||||
if (!connected_) {
|
if (!connected_) {
|
||||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||||
}
|
}
|
||||||
opened_ = connected_;
|
opened_ = connected_;
|
||||||
if (connected_) {
|
if (connected_) {
|
||||||
connecting_ = false;
|
|
||||||
connected();
|
connected();
|
||||||
}
|
}
|
||||||
return connected_;
|
return connected_;
|
||||||
@@ -728,7 +732,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
errorClear();
|
errorClear();
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
{
|
{
|
||||||
long wr = waitForEvent(FD_READ | FD_CLOSE);
|
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||||
switch (wr) {
|
switch (wr) {
|
||||||
case FD_READ:
|
case FD_READ:
|
||||||
//piCout << "fd_read ...";
|
//piCout << "fd_read ...";
|
||||||
@@ -760,7 +764,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (connected_) {
|
if (connected_) {
|
||||||
//piCoutObj << "Disconnect on read," << ethErrorString();
|
piCoutObj << "Disconnect on read," << ethErrorString();
|
||||||
opened_ = connected_ = false;
|
opened_ = connected_ = false;
|
||||||
closeSocket(sock);
|
closeSocket(sock);
|
||||||
init();
|
init();
|
||||||
@@ -777,7 +781,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
memset(&PRIVATE->raddr_, 0, sizeof(PRIVATE->raddr_));
|
memset(&PRIVATE->raddr_, 0, sizeof(PRIVATE->raddr_));
|
||||||
//piCoutObj << "read from" << path() << "...";
|
//piCoutObj << "read from" << path() << "...";
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long wr = waitForEvent(FD_READ | FD_CLOSE);
|
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||||
switch (wr) {
|
switch (wr) {
|
||||||
case FD_READ:
|
case FD_READ:
|
||||||
//piCout << "fd_read ...";
|
//piCout << "fd_read ...";
|
||||||
@@ -829,7 +833,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
|||||||
#endif
|
#endif
|
||||||
, (sockaddr * )&PRIVATE->saddr_, sizeof(PRIVATE->saddr_));
|
, (sockaddr * )&PRIVATE->saddr_, sizeof(PRIVATE->saddr_));
|
||||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||||
case TCP_Client:
|
case TCP_Client: {
|
||||||
if (connecting_) {
|
if (connecting_) {
|
||||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||||
addr_r.set(path());
|
addr_r.set(path());
|
||||||
@@ -850,15 +854,44 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!connected_) return -1;
|
if (!connected_) return -1;
|
||||||
ret = ::send(sock, (const char *)data, max_size, 0);
|
auto disconnectFunc = [this](){
|
||||||
if (ret < 0) {
|
|
||||||
piCoutObj << "Disconnect on write," << ethErrorString();
|
piCoutObj << "Disconnect on write," << ethErrorString();
|
||||||
opened_ = connected_ = false;
|
opened_ = connected_ = false;
|
||||||
closeSocket(sock);
|
closeSocket(sock);
|
||||||
init();
|
init();
|
||||||
disconnected(true);
|
disconnected(true);
|
||||||
|
};
|
||||||
|
if (!isOptionSet(BlockingWrite)) {
|
||||||
|
ret = ::send(sock, (const char *)data, max_size, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
disconnectFunc();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ssize_t remain_size = max_size;
|
||||||
|
const char * remain_data = (const char *)data;
|
||||||
|
while (remain_size > 0) {
|
||||||
|
int sr = ::send(sock, remain_data, remain_size, 0);
|
||||||
|
if (sr < 0) {
|
||||||
|
int err = ethErrorCore();
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (err == WSAEWOULDBLOCK) {
|
||||||
|
#else
|
||||||
|
if (err == EAGAIN || err == EWOULDBLOCK) {
|
||||||
|
#endif
|
||||||
|
piMinSleep();
|
||||||
|
//piCoutObj << "wait for write";
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
disconnectFunc();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remain_data += sr;
|
||||||
|
remain_size -= sr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -897,7 +930,7 @@ void PIEthernet::server_func(void * eth) {
|
|||||||
sockaddr_in client_addr;
|
sockaddr_in client_addr;
|
||||||
socklen_t slen = sizeof(client_addr);
|
socklen_t slen = sizeof(client_addr);
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long wr = ce->waitForEvent(FD_ACCEPT | FD_CLOSE);
|
long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE);
|
||||||
if (wr != FD_ACCEPT) {
|
if (wr != FD_ACCEPT) {
|
||||||
piMSleep(10);
|
piMSleep(10);
|
||||||
return;
|
return;
|
||||||
@@ -954,7 +987,7 @@ bool PIEthernet::connectTCP() {
|
|||||||
::connect(sock, (sockaddr * )&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
::connect(sock, (sockaddr * )&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
||||||
//piCout << errorString();
|
//piCout << errorString();
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long wr = waitForEvent(FD_CONNECT | FD_CLOSE);
|
long wr = waitForEvent(PRIVATE->event, FD_CONNECT | FD_CLOSE);
|
||||||
switch (wr) {
|
switch (wr) {
|
||||||
case FD_CONNECT:
|
case FD_CONNECT:
|
||||||
//piCout << "fd_connect ...";
|
//piCout << "fd_connect ...";
|
||||||
@@ -975,16 +1008,16 @@ bool PIEthernet::connectTCP() {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long PIEthernet::waitForEvent(long mask) {
|
long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||||
if (!PRIVATE->event.isCreate() || sock < 0) return 0;
|
if (!event.isCreate() || sock < 0) return 0;
|
||||||
WSAEventSelect(sock, PRIVATE->event.getEvent(), mask);
|
WSAEventSelect(sock, event.getEvent(), mask);
|
||||||
if (PRIVATE->event.wait()) {
|
if (event.wait()) {
|
||||||
//DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
|
//DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
|
||||||
//piCout << "wait result" << wr;
|
//piCout << "wait result" << wr;
|
||||||
//if (wr == WSA_WAIT_EVENT_0) {
|
//if (wr == WSA_WAIT_EVENT_0) {
|
||||||
WSANETWORKEVENTS events;
|
WSANETWORKEVENTS events;
|
||||||
memset(&events, 0, sizeof(events));
|
memset(&events, 0, sizeof(events));
|
||||||
WSAEnumNetworkEvents(sock, PRIVATE->event.getEvent(), &events);
|
WSAEnumNetworkEvents(sock, event.getEvent(), &events);
|
||||||
//piCout << "wait result" << events.lNetworkEvents;
|
//piCout << "wait result" << events.lNetworkEvents;
|
||||||
return events.lNetworkEvents;
|
return events.lNetworkEvents;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ private:
|
|||||||
void setType(Type t, bool reopen = true);
|
void setType(Type t, bool reopen = true);
|
||||||
bool connectTCP();
|
bool connectTCP();
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
long waitForEvent(long mask);
|
long waitForEvent(PIWaitEvent & event, long mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ethErrorCore();
|
static int ethErrorCore();
|
||||||
|
|||||||
@@ -840,7 +840,7 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
int err = errno;
|
int err = errno;
|
||||||
if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) {
|
if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) {
|
||||||
softStopThreadedRead();
|
stopThreadedRead();
|
||||||
close();
|
close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user