mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 19:54:57 +08:00
Found an error in my buffering code and added a timeout
to write
This commit is contained in:
parent
8b2c7d4359
commit
49ae058770
@ -265,7 +265,6 @@ Serial::SerialImpl::read (char* buf, size_t size)
|
||||
bytes_read = ::read (fd_, buf, size);
|
||||
// read should always return some data as select reported it was
|
||||
// ready to read when we get to this point.
|
||||
// printf("bytes_read: %lu\n", bytes_read);
|
||||
if (bytes_read < 1)
|
||||
{
|
||||
// Disconnected devices, at least on Linux, show the
|
||||
@ -292,24 +291,53 @@ Serial::SerialImpl::write (const string &data)
|
||||
throw PortNotOpenedException ("Serial::write");
|
||||
}
|
||||
|
||||
ssize_t n = ::write (fd_, data.c_str (), data.length ());
|
||||
fd_set writefds;
|
||||
ssize_t bytes_written = 0;
|
||||
while (true)
|
||||
{
|
||||
if (timeout_ != -1)
|
||||
{
|
||||
FD_ZERO (&writefds);
|
||||
FD_SET (fd_, &writefds);
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = timeout_ / 1000;
|
||||
timeout.tv_usec = static_cast<int> (timeout_ % 1000) * 1000;
|
||||
int r = select (fd_ + 1, NULL, &writefds, NULL, &timeout);
|
||||
|
||||
if (n != static_cast<ssize_t> (data.length ()))
|
||||
{
|
||||
throw IOException ("Write did not complete");
|
||||
}
|
||||
else if (n == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return write (data);
|
||||
}
|
||||
else
|
||||
if (r == -1 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (r == -1)
|
||||
{
|
||||
throw IOException (errno);
|
||||
}
|
||||
}
|
||||
return static_cast<size_t> (n);
|
||||
|
||||
if (timeout_ == -1 || FD_ISSET (fd_, &writefds))
|
||||
{
|
||||
bytes_written = ::write (fd_, data.c_str (), data.length ());
|
||||
// read should always return some data as select reported it was
|
||||
// ready to read when we get to this point.
|
||||
if (bytes_written < 1)
|
||||
{
|
||||
// Disconnected devices, at least on Linux, show the
|
||||
// behavior that they are always ready to read immediately
|
||||
// but reading returns nothing.
|
||||
throw SerialExecption ("device reports readiness to read but "
|
||||
"returned no data (device disconnected?)");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bytes_written != static_cast<ssize_t> (data.length ()))
|
||||
{
|
||||
throw IOException ("Write did not complete");
|
||||
}
|
||||
return static_cast<size_t> (bytes_written);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -91,7 +91,7 @@ Serial::read (size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Needs to read, loop until we have read enough... or timeout
|
||||
// Needs to read, loop until we have read enough or timeout
|
||||
size_t chars_left = 0;
|
||||
string result = "";
|
||||
|
||||
@ -114,8 +114,8 @@ Serial::read (size_t size)
|
||||
*(read_cache_ + chars_read) = '\0';
|
||||
if (chars_left > chars_read)
|
||||
{
|
||||
result.append (read_cache_, chars_read);
|
||||
memset (read_cache_, 0, buffer_size_);
|
||||
result.append (read_cache_);
|
||||
chars_left -= chars_read;
|
||||
}
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user