1
0
mirror of https://github.com/wjwwood/serial.git synced 2026-01-23 04:04:54 +08:00

Found an error in my buffering code and added a timeout

to write
This commit is contained in:
John Harrison 2012-01-23 14:28:16 -06:00
parent 8b2c7d4359
commit 49ae058770
2 changed files with 43 additions and 15 deletions

View File

@ -265,7 +265,6 @@ Serial::SerialImpl::read (char* buf, size_t size)
bytes_read = ::read (fd_, buf, size); bytes_read = ::read (fd_, buf, size);
// read should always return some data as select reported it was // read should always return some data as select reported it was
// ready to read when we get to this point. // ready to read when we get to this point.
// printf("bytes_read: %lu\n", bytes_read);
if (bytes_read < 1) if (bytes_read < 1)
{ {
// Disconnected devices, at least on Linux, show the // Disconnected devices, at least on Linux, show the
@ -292,24 +291,53 @@ Serial::SerialImpl::write (const string &data)
throw PortNotOpenedException ("Serial::write"); 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 ())) if (r == -1 && errno == EINTR)
{ continue;
throw IOException ("Write did not complete");
} if (r == -1)
else if (n == -1)
{
if (errno == EINTR)
{
return write (data);
}
else
{ {
throw IOException (errno); 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 void

View File

@ -91,7 +91,7 @@ Serial::read (size_t size)
} }
else 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; size_t chars_left = 0;
string result = ""; string result = "";
@ -114,8 +114,8 @@ Serial::read (size_t size)
*(read_cache_ + chars_read) = '\0'; *(read_cache_ + chars_read) = '\0';
if (chars_left > chars_read) if (chars_left > chars_read)
{ {
result.append (read_cache_, chars_read);
memset (read_cache_, 0, buffer_size_); memset (read_cache_, 0, buffer_size_);
result.append (read_cache_);
chars_left -= chars_read; chars_left -= chars_read;
} }
else else