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

Fixed some memory problems on destruction. Serial listener maybe working, serial's read doesn't seem to return anything or block at all.

This commit is contained in:
William Woodall 2012-01-12 01:15:04 -06:00
parent 2f36f14e1a
commit 48a30ec4ff
5 changed files with 57 additions and 33 deletions

View File

@ -13,9 +13,9 @@ void callback(std::string token) {
std::cout << "callback got a: " << token << std::endl; std::cout << "callback got a: " << token << std::endl;
} }
int main(void) { int run() {
// Assuming this device prints the string 'pre-substr-post\r' at 100Hz // Assuming this device prints the string 'pre-substr-post\r' at 100Hz
Serial serial("/dev/tty.usbmodemfd1231", 115200); Serial serial("/dev/tty.usbserial-A900cfJA", 115200);
SerialListener listener; SerialListener listener;
listener.startListening(serial); listener.startListening(serial);
@ -40,7 +40,7 @@ int main(void) {
listener.createBlockingFilter(SerialListener::endsWith("post")); listener.createBlockingFilter(SerialListener::endsWith("post"));
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
std::string token = f2->wait(100); // Wait for 100 ms or a matched token std::string token = f2->wait(100); // Wait for 100 ms or a matched token
if (token == "") if (token != "")
std::cout << "Found something ending with 'post'" << std::endl; std::cout << "Found something ending with 'post'" << std::endl;
else else
std::cout << "Did not find something ending with 'post'" << std::endl; std::cout << "Did not find something ending with 'post'" << std::endl;
@ -82,3 +82,12 @@ int main(void) {
return 0; return 0;
} }
int main(void) {
try {
return run();
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
return 1;
}
}

View File

@ -814,12 +814,10 @@ private:
class BlockingFilter class BlockingFilter
{ {
public: public:
BlockingFilter (ComparatorType comparator, BlockingFilter (ComparatorType comparator, SerialListener &listener) {
boost::shared_ptr<SerialListener> listener) this->listener = &listener;
: listener(listener)
{
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1); DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
this->filter_ptr = listener->createFilter(comparator, cb); this->filter_ptr = this->listener->createFilter(comparator, cb);
} }
virtual ~BlockingFilter () { virtual ~BlockingFilter () {
@ -851,7 +849,7 @@ public:
} }
private: private:
boost::shared_ptr<SerialListener> listener; SerialListener * listener;
boost::condition_variable cond; boost::condition_variable cond;
boost::mutex mutex; boost::mutex mutex;
std::string result; std::string result;
@ -878,11 +876,12 @@ class BufferedFilter
{ {
public: public:
BufferedFilter (ComparatorType comparator, size_t buffer_size, BufferedFilter (ComparatorType comparator, size_t buffer_size,
boost::shared_ptr<SerialListener> listener) SerialListener &listener)
: listener(listener), buffer_size(buffer_size) : buffer_size(buffer_size)
{ {
this->listener = &listener;
DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1); DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1);
this->filter_ptr = listener->createFilter(comparator, cb); this->filter_ptr = this->listener->createFilter(comparator, cb);
} }
virtual ~BufferedFilter () { virtual ~BufferedFilter () {
@ -944,7 +943,7 @@ public:
private: private:
size_t buffer_size; size_t buffer_size;
boost::shared_ptr<SerialListener> listener; SerialListener * listener;
ConcurrentQueue<std::string> queue; ConcurrentQueue<std::string> queue;
std::string result; std::string result;

View File

@ -16,6 +16,7 @@ IF(EXISTS /usr/bin/clang)
set(CMAKE_OSX_DEPLOYMENT_TARGET "") set(CMAKE_OSX_DEPLOYMENT_TARGET "")
# set(CMAKE_CXX_FLAGS "-ferror-limit=5 -std=c++0x -stdlib=libc++") # set(CMAKE_CXX_FLAGS "-ferror-limit=5 -std=c++0x -stdlib=libc++")
set(CMAKE_CXX_FLAGS "-ferror-limit=5") set(CMAKE_CXX_FLAGS "-ferror-limit=5")
set(CMAKE_BUILD_TYPE Debug)
ENDIF(EXISTS /usr/bin/clang) ENDIF(EXISTS /usr/bin/clang)
option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF) option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF)

View File

@ -22,6 +22,20 @@
#endif #endif
#endif #endif
class UnhandledException : public std::exception {
const char * e_what;
public:
UnhandledException(const char * e_what) {this->e_what = e_what;}
virtual const char* what() const throw() {
std::stringstream ss;
ss << "Unhandled Exception: " << this->e_what;
return ss.str().c_str();
}
};
typedef UnhandledException e;
using ::serial::Serial; using ::serial::Serial;
using std::string; using std::string;
@ -42,8 +56,8 @@ Serial::SerialImpl::~SerialImpl () {
void void
Serial::SerialImpl::open () { Serial::SerialImpl::open () {
if (port_.empty() == false) throw "error"; if (port_.empty() == true) throw e("error");
if (isOpen_ == false) throw "error"; if (isOpen_ == true) throw e("error");
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
@ -55,7 +69,7 @@ Serial::SerialImpl::open () {
void void
Serial::SerialImpl::reconfigurePort () { Serial::SerialImpl::reconfigurePort () {
if (fd_ == -1) throw "Error"; // Can only operate on a valid file descriptor if (fd_ == -1) throw e("Error"); // Can only operate on a valid file descriptor
struct termios options; // The current options for the file descriptor struct termios options; // The current options for the file descriptor
struct termios originalTTYAttrs; // The orignal file descriptor options struct termios originalTTYAttrs; // The orignal file descriptor options
@ -66,7 +80,7 @@ Serial::SerialImpl::reconfigurePort () {
vtime = int(interCharTimeout_ * 10); vtime = int(interCharTimeout_ * 10);
} }
if (tcgetattr(fd_, &originalTTYAttrs) == -1) throw "Error"; if (tcgetattr(fd_, &originalTTYAttrs) == -1) throw e("Error");
options = originalTTYAttrs; options = originalTTYAttrs;
@ -99,7 +113,7 @@ Serial::SerialImpl::reconfigurePort () {
else if (bytesize_ == FIVEBITS) else if (bytesize_ == FIVEBITS)
options.c_cflag |= CS5; options.c_cflag |= CS5;
else else
throw "ValueError(Invalid char len: %%r)"; throw e("ValueError(Invalid char len: %%r)");
// setup stopbits // setup stopbits
if (stopbits_ == STOPBITS_ONE) if (stopbits_ == STOPBITS_ONE)
options.c_cflag &= ~(CSTOPB); options.c_cflag &= ~(CSTOPB);
@ -108,7 +122,7 @@ Serial::SerialImpl::reconfigurePort () {
else if (stopbits_ == STOPBITS_TWO) else if (stopbits_ == STOPBITS_TWO)
options.c_cflag |= (CSTOPB); options.c_cflag |= (CSTOPB);
else else
throw "ValueError(Invalid stop bit specification:)"; throw e("ValueError(Invalid stop bit specification:)");
// setup parity // setup parity
options.c_iflag &= ~(INPCK|ISTRIP); options.c_iflag &= ~(INPCK|ISTRIP);
if (parity_ == PARITY_NONE) { if (parity_ == PARITY_NONE) {
@ -122,7 +136,7 @@ Serial::SerialImpl::reconfigurePort () {
options.c_cflag |= (PARENB|PARODD); options.c_cflag |= (PARENB|PARODD);
} }
else { else {
throw "ValueError(Invalid parity:"; throw e("ValueError(Invalid parity:");
} }
// setup flow control // setup flow control
// xonxoff // xonxoff
@ -188,13 +202,13 @@ Serial::SerialImpl::available () {
if (result == 0) { if (result == 0) {
return count; return count;
} else { } else {
throw "Error"; throw e("Error");
} }
} }
string string
Serial::SerialImpl::read (size_t size) { Serial::SerialImpl::read (size_t size) {
if (!isOpen_) throw "PortNotOpenError()"; if (!isOpen_) throw e("PortNotOpenError()");
string message = ""; string message = "";
char buf[1024]; char buf[1024];
fd_set readfds; fd_set readfds;
@ -223,7 +237,7 @@ Serial::SerialImpl::read (size_t size) {
// Disconnected devices, at least on Linux, show the // Disconnected devices, at least on Linux, show the
// behavior that they are always ready to read immediately // behavior that they are always ready to read immediately
// but reading returns nothing. // but reading returns nothing.
throw "SerialException('device reports readiness to read but returned no data (device disconnected?)')"; throw e("SerialException('device reports readiness to read but returned no data (device disconnected?)')");
} }
message.append(buf, bytes_read); message.append(buf, bytes_read);
} }
@ -236,12 +250,12 @@ Serial::SerialImpl::read (size_t size) {
size_t size_t
Serial::SerialImpl::write (const string &data) { Serial::SerialImpl::write (const string &data) {
if (isOpen_ == false) throw "portNotOpenError"; if (isOpen_ == false) throw e("portNotOpenError");
size_t t = data.length(); size_t t = data.length();
size_t n = ::write(fd_, data.c_str(), data.length()); size_t n = ::write(fd_, data.c_str(), data.length());
if (n == -1) { if (n == -1) {
throw "Write error"; throw e("Write error");
} }
return n; return n;
} }

View File

@ -64,6 +64,8 @@ SerialListener::callback() {
std::pair<FilterPtr,TokenPtr> pair; std::pair<FilterPtr,TokenPtr> pair;
while (this->listening) { while (this->listening) {
if (this->callback_queue.timed_wait_and_pop(pair, 10)) { if (this->callback_queue.timed_wait_and_pop(pair, 10)) {
std::cout << "Got something off the callback queue: ";
std::cout << (*pair.second) << std::endl;
if (this->listening) { if (this->listening) {
try { try {
pair.first->callback((*pair.second)); pair.first->callback((*pair.second));
@ -133,6 +135,7 @@ SerialListener::readSomeData(std::string &temp, size_t this_many) {
this->handle_exc(SerialListenerException("Serial port not open.")); this->handle_exc(SerialListenerException("Serial port not open."));
} }
temp = this->serial_port->read(this_many); temp = this->serial_port->read(this_many);
std::cout << "Read(" << temp.length() << "): " << temp << std::endl;
} }
void void
@ -199,7 +202,7 @@ SerialListener::createFilter(ComparatorType comparator, DataCallback callback)
BlockingFilterPtr BlockingFilterPtr
SerialListener::createBlockingFilter(ComparatorType comparator) { SerialListener::createBlockingFilter(ComparatorType comparator) {
return BlockingFilterPtr( return BlockingFilterPtr(
new BlockingFilter(comparator, boost::shared_ptr<SerialListener>(this))); new BlockingFilter(comparator, (*this)));
} }
BufferedFilterPtr BufferedFilterPtr
@ -207,9 +210,7 @@ SerialListener::createBufferedFilter(ComparatorType comparator,
size_t buffer_size) size_t buffer_size)
{ {
return BufferedFilterPtr( return BufferedFilterPtr(
new BufferedFilter(comparator, new BufferedFilter(comparator, buffer_size, (*this)));
buffer_size,
boost::shared_ptr<SerialListener>(this)));
} }
void void