[asio] reopening of serial port fails - why?

Hi!
The code below perfectly reads characters from the serial line
for 6 seconds. The termination of the thread and a reopening
of the connection then fails.
What am i missing here?
Markus
---snip---
// TestBoostAsio.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}
/* minicom.cpp
A simple demonstration minicom client with Boost asio
Parameters:
baud rate
serial port (eg /dev/ttyS0 or COM1)
To end the application, send Ctrl-C on standard input
*/
#include <deque>
#include <iostream>
#include

Markus Werle wrote:
Hi!
The code below perfectly reads characters from the serial line for 6 seconds. The termination of the thread and a reopening of the connection then fails.
What am i missing here?
Markus
... snip ...
boost::asio::io_service io_service; // define an instance of the main class of this program minicom_client c(io_service, boost::lexical_cast<unsigned int> (argv[1]), argv[2]); // run the IO service as a separate thread, so the main thread can block on standard input
while (true) // PROBLEM: reentering this loop fails - why? {
You need to call reset() on the io_service instance before you can call run() for a second time.
boost::thread t(boost::bind (&boost::asio::io_service::run, &io_service));
... snip ... HTH Bill Somerville

Bill Somerville
You need to call reset() on the io_service instance before you can call run() for a second time.
I tried this: while (true) // PROBLEM: reentering this loop fails - why? { io_service.reset(); boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); [...] Now the reconnection does not succeed either and after some tries I obtain an invalid file handle error. I guess I am missing some fundamental thing with asio ... Markus

Markus Werle wrote:
Bill Somerville
writes: You need to call reset() on the io_service instance before you can call run() for a second time.
I tried this:
while (true) // PROBLEM: reentering this loop fails - why? { io_service.reset(); boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); [...]
Now the reconnection does not succeed either and after some tries I obtain an invalid file handle error.
You didn't say how the first version or this version fails, an error message or some unexpected behaviour would help.
I guess I am missing some fundamental thing with asio ...
Markus
-- Bill Somerville

Bill Somerville
You didn't say how the first version or this version fails, an error message or some unexpected behaviour would help.
[... snipped nearly all read chars in 6s ...]
55565758595a5b5c5d5e5f60616Error: Connection did not succeed.
Press Enter to exit
-------------------
-------------------
Error: Connection did not succeed.
Press Enter to exit
Press Enter to exit
Error: Das angegebene Dateihandle ist ung³ltig
(last sentence: invalid file handle)
Actual Code:
// TestBoostAsio.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}
/* minicom.cpp
A simple demonstration minicom client with Boost asio
Parameters:
baud rate
serial port (eg /dev/ttyS0 or COM1)
To end the application, send Ctrl-C on standard input
*/
#include <deque>
#include <iostream>
#include

Markus Werle
while (true) // PROBLEM: reentering this loop fails - why? { io_service.reset(); boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); [...]
Now the reconnection does not succeed either and after some tries I obtain an invalid file handle error.
I guess I am missing some fundamental thing with asio ...
... or maybe it is some bug.
http://stackoverflow.com/questions/541062/boostasioserialport-reading-after-
reconnecting-device
Any further comment?
This code here still does not work:
// TestBoostAsio.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}
/* minicom.cpp
A simple demonstration minicom client with Boost asio
Parameters:
baud rate
serial port (eg /dev/ttyS0 or COM1)
To end the application, send Ctrl-C on standard input
*/
#include <deque>
#include <iostream>
#include

Markus Werle wrote:
Markus Werle
writes: while (true) // PROBLEM: reentering this loop fails - why? { io_service.reset(); boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); [...]
Now the reconnection does not succeed either and after some tries I obtain an invalid file handle error.
I guess I am missing some fundamental thing with asio ...
... or maybe it is some bug. http://stackoverflow.com/questions/541062/boostasioserialport-reading-after- reconnecting-device
Any further comment?
I think you should simplify your close semantics, passing an error code to your do_close() method is making it do more work than necessary. I don't understand the recreation of the serial_port object although I have not used the serial_port functionality myself. Also the close() method posts a do_close() call with a default constructed error object which is not handled correctly. I'm not sure why you need to use a loop in the main routine, if you want a server then use pending async calls to keep the io_service alive, if you want a client then perhaps errors should simply cause graceful termination. ... snip ... HTH -- Bill Somerville

Bill Somerville
I think you should simplify your close semantics, passing an error code to your do_close() method is making it do more work than necessary.
I am an absolute beginner with asio. I read through the docs and the examples, but obviously missed some points. The example I presented is stolen from the web from http://www.nabble.com/Simple-serial-port-demonstration-with-boost-asio- asynchronous-I-O-td19849520.html
I don't understand the recreation of the serial_port object although I have not used the serial_port functionality myself. Also the close() method posts a do_close() call with a default constructed error object which is not handled correctly.
In my GUI application I have 2 buttons: connect/disconnect. I simply want them to work and I probably want to switch ports during runtime. So here is my nitty-gritty task: Write a class with the following interface class SerialLineCommunicator { public: Connect (std::string const & PortName); Disconnect(); WriteToSerialPort(std::string const & Text); }; This class should write all received characters to std::cout. The problem I have is: The Disconnect() method seems to have some problems which I was trying to track down, but I got lost. Neither a close() nor a delete of thread or communicator resolves the issue. I found that the demo code I had stolen from the internet obviously has the same problem if adopted such that it terminates the connection and then retakes it. I have not found any other working demo code and the docs are not helpful to me either.
I'm not sure why you need to use a loop in the main routine, if you want a server then use pending async calls to keep the io_service alive, if you want a client then perhaps errors should simply cause graceful termination.
Can you probably provide some code that *should* work? I have no idea anymore. Thanks, Markus

I tried this:
while (true) // PROBLEM: reentering this loop fails - why? { io_service.reset(); boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); [...]
Now the reconnection does not succeed either and after some tries I obtain an invalid file handle error.
It seems that you open your serial_port object in the constructor "minicom_client" wrapper. But you create it only once, before the loop starts, don't you? So after you explicitly close serial_port, no one opens it.

Igor R
It seems that you open your serial_port object in the constructor "minicom_client" wrapper. But you create it only once, before the loop starts, don't you? So after you explicitly close serial_port, no one opens it.
Ooops!
So many tries and errors until such a stupid error.
Now I got it.
Rules are:
- first start do_read(),
- then start the thread
- after termination of the thread an io_service_.reset()
is mandatory. Otherwise subsequent thread starts lead to
spurious behaviour. This was not clear to me and I dislike
this behaviour ...
Working code below.
Markus
---snip---
// TestBoostAsio.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}
/* minicom.cpp
A simple demonstration minicom client with Boost asio
Parameters:
baud rate
serial port (eg /dev/ttyS0 or COM1)
To end the application, send Ctrl-C on standard input
*/
#include <deque>
#include <iostream>
#include

Rules are:
- first start do_read(), - then start the thread - after termination of the thread an io_service_.reset() is mandatory. Otherwise subsequent thread starts lead to spurious behaviour. This was not clear to me and I dislike this behaviour ...
ASIO reference explicitly states that you must call io_service::reset() before subsequent call to io_service::run(). However, you didn't have to exit the thread that runs io_service::run() - this's just matter of design. In the asio examples you can find other design choices.
participants (3)
-
Bill Somerville
-
Igor R
-
Markus Werle