[Boost-users] [asio] reopening of serial port fails - why?

773 views
Skip to first unread message

Markus Werle

unread,
Mar 6, 2009, 4:43:10 AM3/6/09
to boost...@lists.boost.org
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 <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>

#include <iostream>


#ifdef POSIX
#include <termios.h>
#endif

using namespace std;

class minicom_client
{
public:
minicom_client(boost::asio::io_service& io_service,
unsigned int baud,
const string& device)
: active_(true),
io_service_(io_service),
serialPort(io_service, device)
{
if (!serialPort.is_open())
{
cerr << "Failed to open serial port\n";
return;
}
boost::asio::serial_port_base::baud_rate baud_option(baud);
serialPort.set_option(baud_option); // set the baud rate after
the port has been opened
read_start();
}

void write(const char msg) // pass the write data to the do_write
function via the io service in the other thread
{
io_service_.post(boost::bind(&minicom_client::do_write, this,
msg));
}

void close() // call the do_close function via the io service in the
other thread
{
io_service_.post(boost::bind(&minicom_client::do_close, this,
boost::system::error_code()));
}

bool active() // return true if the socket is still active
{
return active_;
}

private:

static const int max_read_length = 512; // maximum amount of data to
read in one operation

void read_start(void)
{ // Start an asynchronous read and call read_complete when it
completes or fails
serialPort.async_read_some(boost::asio::buffer(read_msg_,
max_read_length),
boost::bind
(&minicom_client::read_complete,

this,

boost::asio::placeholders::error,

boost::asio::placeholders::bytes_transferred));
}

void read_complete(const boost::system::error_code& error, size_t
bytes_transferred)
{ // the asynchronous read operation has now completed or failed and
returned an error
if (!error)
{ // read completed, so process the data
cout.write(read_msg_, bytes_transferred); // echo to
standard output
read_start(); // start waiting for another asynchronous
read again
}
else
do_close(error);
}

void do_write(const char msg)
{ // callback to handle write call from outside this class
bool write_in_progress = !write_msgs_.empty(); // is there
anything currently being written?
write_msgs_.push_back(msg); // store in write buffer
if (!write_in_progress) // if nothing is currently being
written, then start
write_start();
}

void write_start(void)
{ // Start an asynchronous write and call write_complete when it
completes or fails
boost::asio::async_write(serialPort,

boost::asio::buffer(&write_msgs_.front(), 1),
boost::bind
(&minicom_client::write_complete,

this,

boost::asio::placeholders::error));
}

void write_complete(const boost::system::error_code& error)
{ // the asynchronous read operation has now completed or failed and
returned an error
if (!error)
{ // write completed, so send next write data
write_msgs_.pop_front(); // remove the completed data
if (!write_msgs_.empty()) // if there is anthing left
to be written
write_start(); // then start sending the next
item in the buffer
}
else
do_close(error);
}

void do_close(const boost::system::error_code& error)
{ // something has gone wrong, so close the socket & make this object
inactive
if (error == boost::asio::error::operation_aborted) // if this
call is the result of a timer cancel()
return; // ignore it because the connection cancelled
the timer
if (error)
cerr << "Error: " << error.message() << endl; // show
the error message
else
cout << "Error: Connection did not succeed.\n";
cout << "Press Enter to exit\n";
serialPort.close();
active_ = false;
}

private:
bool active_; // remains true while this object is still operating
boost::asio::io_service& io_service_; // the main IO service that runs
this connection
boost::asio::serial_port serialPort; // the serial port this instance
is connected to
char read_msg_[max_read_length]; // data read from the socket
deque<char> write_msgs_; // buffered write data
};

int main(int argc, char* argv[])
{
// on Unix POSIX based systems, turn off line buffering of input, so cin.get()
returns after every keypress
// On other systems, you'll need to look for an equivalent
#ifdef POSIX
termios stored_settings;
tcgetattr(0, &stored_settings);
termios new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ISIG); // don't automatically handle control-
C
tcsetattr(0, TCSANOW, &new_settings);
#endif
try
{
if (argc != 3)
{
cerr << "Usage: minicom <baud> <device>\n";
return 1;
}


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?
{
boost::thread t(boost::bind
(&boost::asio::io_service::run, &io_service));

boost::asio::io_service io;
boost::asio::deadline_timer timer(io,
boost::posix_time::seconds(3));
timer.wait();

c.write('a');

boost::asio::deadline_timer timer2(io,
boost::posix_time::seconds(3));
timer2.wait();

//while (c.active()) // check the internal state of the
connection to make sure it's still running
//{
// char ch;
// cin.get(ch); // blocking wait for standard
input
// if (ch == 32) // ctrl-C to end program
// break;
// c.write(ch);
//}
c.close(); // close the minicom client connection
t.join(); // wait for the IO service thread to close
std::cout << "-------------------" << std::endl;
}
}
catch (exception& e)
{
cerr << "Exception: " << e.what() << "\n";
}
#ifdef POSIX // restore default buffering of standard input
tcsetattr(0, TCSANOW, &stored_settings);
#endif
return 0;
}


_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Bill Somerville

unread,
Mar 6, 2009, 4:51:44 AM3/6/09
to boost...@lists.boost.org
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

Markus Werle

unread,
Mar 6, 2009, 4:57:28 AM3/6/09
to boost...@lists.boost.org
Bill Somerville <bill <at> classdesign.com> 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.

I guess I am missing some fundamental thing with asio ...

Markus

Bill Somerville

unread,
Mar 6, 2009, 5:22:21 AM3/6/09
to boost...@lists.boost.org
Markus Werle wrote:
> Bill Somerville <bill <at> classdesign.com> 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

Markus Werle

unread,
Mar 6, 2009, 5:57:03 AM3/6/09
to boost...@lists.boost.org
Markus Werle <numerical.simulation <at> web.de> 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?

This code here still does not work:

#include "stdafx.h"

#include <iostream>

using namespace std;

baudRate_(baud),
device_(device),
io_service_(io_service),
pSerialPort_(new boost::asio::serial_port(io_service,
device))
{
if (!pSerialPort_->is_open())

{
cerr << "Failed to open serial port\n";
return;
}
boost::asio::serial_port_base::baud_rate baud_option(baud);

pSerialPort_->set_option(baud_option); // set the baud rate

after the port has been opened
read_start();
}

void write(const char msg) // pass the write data to the do_write
function via the io service in the other thread
{
io_service_.post(boost::bind(&minicom_client::do_write, this,
msg));
}

void close() // call the do_close function via the io service in the
other thread
{
io_service_.post(boost::bind(&minicom_client::do_close, this,
boost::system::error_code()));
}

bool active() // return true if the socket is still active
{
return active_;
}

private:

static const int max_read_length = 512; // maximum amount of data to
read in one operation

void read_start(void)
{ // Start an asynchronous read and call read_complete when it
completes or fails

pSerialPort_->async_read_some(boost::asio::buffer(read_msg_,

boost::asio::async_write(*pSerialPort_,

pSerialPort_->close();

if (pSerialPort_->is_open())
{
delete pSerialPort_;
pSerialPort_ = new boost::asio::serial_port
(io_service_, device_);

boost::asio::serial_port_base::baud_rate baud_option
(baudRate_);
pSerialPort_->set_option(baud_option);
}

active_ = false;
}

private:
bool active_; // remains true while this object is still operating

unsigned int const baudRate_;
const string& device_;


boost::asio::io_service& io_service_; // the main IO service that runs
this connection

boost::asio::serial_port * pSerialPort_; // the serial port this

instance is connected to
char read_msg_[max_read_length]; // data read from the socket
deque<char> write_msgs_; // buffered write data
};

int main(int argc, char* argv[])
{
// on Unix POSIX based systems, turn off line buffering of input, so cin.get()
returns after every keypress
// On other systems, you'll need to look for an equivalent
#ifdef POSIX
termios stored_settings;
tcgetattr(0, &stored_settings);
termios new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ISIG); // don't automatically handle control-
C
tcsetattr(0, TCSANOW, &new_settings);
#endif
try
{
if (argc != 3)
{
cerr << "Usage: minicom <baud> <device>\n";
return 1;
}

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?
{

boost::thread t(boost::bind
(&boost::asio::io_service::run, &io_service));

boost::asio::io_service io;
boost::asio::deadline_timer timer(io,
boost::posix_time::seconds(3));
timer.wait();

c.write('a');

boost::asio::deadline_timer timer2(io,
boost::posix_time::seconds(3));
timer2.wait();

//while (c.active()) // check the internal state of the
connection to make sure it's still running
//{
// char ch;
// cin.get(ch); // blocking wait for standard
input
// if (ch == 32) // ctrl-C to end program
// break;
// c.write(ch);
//}
c.close(); // close the minicom client connection
t.join(); // wait for the IO service thread to close
std::cout << "-------------------" << std::endl;

io_service.reset();


}
}
catch (exception& e)
{
cerr << "Exception: " << e.what() << "\n";
}
#ifdef POSIX // restore default buffering of standard input
tcsetattr(0, TCSANOW, &stored_settings);
#endif
return 0;
}

_______________________________________________

Markus Werle

unread,
Mar 6, 2009, 6:02:33 AM3/6/09
to boost...@lists.boost.org
Bill Somerville <bill <at> classdesign.com> writes:

> 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:

#include "stdafx.h"

#include <iostream>

using namespace std;

baudRate_(baud),
device_(device),
io_service_(io_service),
pSerialPort_(new boost::asio::serial_port(io_service,
device))
{
if (!pSerialPort_->is_open())
{

cerr << "Failed to open serial port\n";
return;
}
boost::asio::serial_port_base::baud_rate baud_option(baud);

pSerialPort_->set_option(baud_option); // set the baud rate

after the port has been opened
read_start();
}

void write(const char msg) // pass the write data to the do_write
function via the io service in the other thread
{
io_service_.post(boost::bind(&minicom_client::do_write, this,
msg));
}

void close() // call the do_close function via the io service in the
other thread
{
io_service_.post(boost::bind(&minicom_client::do_close, this,
boost::system::error_code()));
}

bool active() // return true if the socket is still active
{
return active_;
}

private:

static const int max_read_length = 512; // maximum amount of data to
read in one operation

void read_start(void)
{ // Start an asynchronous read and call read_complete when it
completes or fails

pSerialPort_->async_read_some(boost::asio::buffer(read_msg_,

boost::asio::async_write(*pSerialPort_,

pSerialPort_->close();

if (pSerialPort_->is_open())
{
delete pSerialPort_;
pSerialPort_ = new boost::asio::serial_port
(io_service_, device_);

boost::asio::serial_port_base::baud_rate baud_option
(baudRate_);
pSerialPort_->set_option(baud_option);
}

active_ = false;
}

private:
bool active_; // remains true while this object is still operating

unsigned int const baudRate_;
const string& device_;

boost::asio::io_service& io_service_; // the main IO service that runs
this connection

boost::asio::serial_port * pSerialPort_; // the serial port this

instance is connected to
char read_msg_[max_read_length]; // data read from the socket
deque<char> write_msgs_; // buffered write data
};

int main(int argc, char* argv[])
{
// on Unix POSIX based systems, turn off line buffering of input, so cin.get()
returns after every keypress
// On other systems, you'll need to look for an equivalent
#ifdef POSIX
termios stored_settings;
tcgetattr(0, &stored_settings);
termios new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ISIG); // don't automatically handle control-
C
tcsetattr(0, TCSANOW, &new_settings);
#endif
try
{
if (argc != 3)
{
cerr << "Usage: minicom <baud> <device>\n";
return 1;
}

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?
{

boost::thread t(boost::bind
(&boost::asio::io_service::run, &io_service));

boost::asio::io_service io;
boost::asio::deadline_timer timer(io,
boost::posix_time::seconds(3));
timer.wait();

c.write('a');

boost::asio::deadline_timer timer2(io,
boost::posix_time::seconds(3));
timer2.wait();

//while (c.active()) // check the internal state of the
connection to make sure it's still running
//{
// char ch;
// cin.get(ch); // blocking wait for standard
input
// if (ch == 32) // ctrl-C to end program
// break;
// c.write(ch);
//}
c.close(); // close the minicom client connection
t.join(); // wait for the IO service thread to close
std::cout << "-------------------" << std::endl;

io_service.reset();


}
}
catch (exception& e)
{
cerr << "Exception: " << e.what() << "\n";
}
#ifdef POSIX // restore default buffering of standard input
tcsetattr(0, TCSANOW, &stored_settings);
#endif
return 0;
}

_______________________________________________

Bill Somerville

unread,
Mar 6, 2009, 6:47:02 AM3/6/09
to boost...@lists.boost.org
Markus Werle wrote:
> Markus Werle <numerical.simulation <at> web.de> 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

Igor R

unread,
Mar 6, 2009, 7:53:42 AM3/6/09
to boost...@lists.boost.org
> 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.

Markus Werle

unread,
Mar 6, 2009, 7:57:06 AM3/6/09
to boost...@lists.boost.org
Bill Somerville <bill <at> classdesign.com> writes:


> 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

Markus Werle

unread,
Mar 9, 2009, 5:46:03 AM3/9/09
to boost...@lists.boost.org
Igor R <boost.lists <at> gmail.com> writes:

> 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

#include "stdafx.h"

#include <iostream>

using namespace std;

/*, const string& device */)
: active_(true),
baudRate_(baud),
//device_(device),
io_service_(io_service),
pSerialPort_(new boost::asio::serial_port(io_service/* ,
device*/))
{


}

void write(const char msg) // pass the write data to the do_write
function via the io service in the other thread
{
io_service_.post(boost::bind(&minicom_client::do_write, this,
msg));
}

void open(std::string const & portName)
{
pSerialPort_->open(portName);

if (!pSerialPort_->is_open())

{
cerr << "Failed to open serial port\n";
return;
}
boost::asio::serial_port_base::baud_rate baud_option

(baudRate_);
pSerialPort_->set_option(baud_option); // set the baud rate

after the port has been opened
read_start();
}

void close() // call the do_close function via the io service in the

other thread
{
io_service_.post(boost::bind(&minicom_client::do_close, this,
boost::system::error_code()));
}

bool active() // return true if the socket is still active
{
return active_;
}

private:

static const int max_read_length = 512; // maximum amount of data to
read in one operation

void read_start(void)
{ // Start an asynchronous read and call read_complete when it
completes or fails

pSerialPort_->async_read_some(boost::asio::buffer(read_msg_,

boost::asio::async_write(*pSerialPort_,

//else
//cout << "Error: Connection did not succeed.\n";
cout << "Closing serial port\n";



pSerialPort_->close();

/*if (pSerialPort_->is_open())


{
delete pSerialPort_;
pSerialPort_ = new boost::asio::serial_port
(io_service_, device_);

boost::asio::serial_port_base::baud_rate baud_option
(baudRate_);
pSerialPort_->set_option(baud_option);

}*/

active_ = false;
}

private:
bool active_; // remains true while this object is still operating

unsigned int const baudRate_;
//const string& device_;


boost::asio::io_service& io_service_; // the main IO service that runs
this connection

boost::asio::serial_port * pSerialPort_; // the serial port this

instance is connected to
char read_msg_[max_read_length]; // data read from the socket
deque<char> write_msgs_; // buffered write data
};

int main(int argc, char* argv[])
{
// on Unix POSIX based systems, turn off line buffering of input, so cin.get()
returns after every keypress
// On other systems, you'll need to look for an equivalent
#ifdef POSIX
termios stored_settings;
tcgetattr(0, &stored_settings);
termios new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ISIG); // don't automatically handle control-
C
tcsetattr(0, TCSANOW, &new_settings);
#endif
try
{
if (argc != 3)
{
cerr << "Usage: minicom <baud> <device>\n";
return 1;
}

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?
{

std::string port = argv[2];
c.open(port);


boost::thread t(boost::bind
(&boost::asio::io_service::run, &io_service));

boost::asio::io_service io;
boost::asio::deadline_timer timer(io,
boost::posix_time::seconds(3));
timer.wait();

c.write('a');

boost::asio::deadline_timer timer2(io,
boost::posix_time::seconds(3));
timer2.wait();

//while (c.active()) // check the internal state of the
connection to make sure it's still running
//{
// char ch;
// cin.get(ch); // blocking wait for standard
input
// if (ch == 32) // ctrl-C to end program
// break;
// c.write(ch);
//}
c.close(); // close the minicom client connection
t.join(); // wait for the IO service thread to close
std::cout << "-------------------" << std::endl;

io_service.reset();


}
}
catch (exception& e)
{
cerr << "Exception: " << e.what() << "\n";
}
#ifdef POSIX // restore default buffering of standard input
tcsetattr(0, TCSANOW, &stored_settings);
#endif
return 0;
}

_______________________________________________

Igor R

unread,
Mar 9, 2009, 6:07:36 AM3/9/09
to boost...@lists.boost.org
> 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.

Reply all
Reply to author
Forward
0 new messages