Friday, November 10, 2006
Buffer debugging
Some standard library implementations, such as the one that ships with MSVC 8.0, provide a nifty feature called iterator debugging. What this means is that the validity of your iterators is checked at runtime. If you try to use an iterator that has been invalidated, you'll get an assertion. For example:
With the new buffer debug checking, however, Boost.Asio stores an iterator into the string until the asynchronous operation completes, and then dereferences it to check its validity. In the above example you get an assertion failure just before Boost.Asio tries to call the completion handler.
This feature has only been tested with MSVC 8.0 so far, but it should work with any other implementation that supports iterator debugging. Obviously there's a performance cost to this checking, so it's only enabled in debug builds. You can also explicitly disable it by defining
std::vector<int> v(1)Boost.Asio now takes advantage of this feature to add buffer debugging. Consider the following code:
std::vector<int>::iterator i = v.begin();
v.clear(); // invalidates iterators
*i = 0; // assertion!
void dont_do_this()When you call an asynchronous read or write you need to ensure that the buffers for the operation are valid until the completion handler is called. In the above example, the buffer is the
{
std::string msg = "Hello, world!";
asio::async_write(sock, asio::buffer(msg), my_handler);
}
std::string variable msg. This variable is on the stack, and so it goes out of scope before the asynchronous operation completes. If you're lucky, your application will crash. Often you will get random failures.With the new buffer debug checking, however, Boost.Asio stores an iterator into the string until the asynchronous operation completes, and then dereferences it to check its validity. In the above example you get an assertion failure just before Boost.Asio tries to call the completion handler.
This feature has only been tested with MSVC 8.0 so far, but it should work with any other implementation that supports iterator debugging. Obviously there's a performance cost to this checking, so it's only enabled in debug builds. You can also explicitly disable it by defining
BOOST_ASIO_DISABLE_BUFFER_DEBUGGING (or ASIO_DISABLE_BUFFER_DEBUGGING if you're using standalone asio).
Saturday, October 07, 2006
FreeBSD support
Asio has now been tested successfully on FreeBSD 6.0, and should support FreeBSD 5.5 and later. FreeBSD 5.4 and earlier are not supported since, according to the man pages, getaddrinfo is not thread-safe.
Tuesday, September 26, 2006
SSL password callbacks
On the weekend I made some changes to asio to support password callbacks for SSL. There is a new function on the
asio::ssl::context class called set_password_callback(), which takes a function object with the following signature:std::string password_callback(The callback must return the password as a string. The
std::size_t max_length,
ssl::context::password_purpose purpose);
max_length argument indicates the maximum allowable length of the password, and if the returned string is longer it will be truncated. The context::password_purpose type is an enum with values for_reading and for_writing. In most cases you won't need to use the max_length or purpose arguments, and if you use boost::bind() to create the function object you can just leave them off. For example, the SSL server sample included with asio now has the following:context_.set_password_callback(The final thing to note is that the password callback needs to be set before calling any
boost::bind(&server::get_password, this));
...
std::string get_password() const
{
return "test";
}
ssl::context functions that load keys, such as use_private_key_file().
What's this all about?
Greetings, reader. I have a blog. Now what? Well, the plan is to post ideas, tips and tricks, design thoughts, and anything else related to C++, Boost.Asio and programming that happens to take my interest.
Subscribe to:
Comments (Atom)