boost asio asynchronously waiting on a condition variable
If I understand the intent correctly, you want to launch an event handler, when some condition variable is signaled, in context of asio thread pool? I think it would be sufficient to wait on the condition variable in the beginning of the handler, and io_service::post() itself back in the pool in the end, something of this sort:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
boost::asio::io_service io;
boost::mutex mx;
boost::condition_variable cv;
void handler()
{
boost::unique_lock<boost::mutex> lk(mx);
cv.wait(lk);
std::cout << "handler awakened\n";
io.post(handler);
}
void buzzer()
{
for(;;)
{
boost::this_thread::sleep(boost::posix_time::seconds(1));
boost::lock_guard<boost::mutex> lk(mx);
cv.notify_all();
}
}
int main()
{
io.post(handler);
boost::thread bt(buzzer);
io.run();
}
boost.asio test problem
The list of all UDP socket constructors if found here. As you can see, you must provide at least a reference to a boost::asio::io_service
object.
If this is a private variable, provide this reference in the class constructor's initializer list. The following will compile:
#include <boost/asio.hpp>
class Socket
{
boost::asio::ip::udp::socket socket_;
public:
Socket( boost::asio::io_service& ioserv) : socket_(ioserv) {}
};
int main()
{
boost::asio::io_service io;
Socket s(io);
}
Boost.Asio throws 'No such device' exception when trying to join multicast group
With no DHCP working, there is no route for multicast.
Use:
route add -net 224.0.0.0/4 dev eth0
Can a boost::asio::yield_context be used as a deadline_timer handler when doing cancel?
The async_wait()
operation is being cancelled, resulting in the asynchronous operation failing with an error code of boost::asio::error::operation_aborted
. As noted in the Stackful Coroutines documentation, when the boost::asio::yield_context
detects that the asynchronous operation has failed, it converts the boost::system::error_code
into a system_error
exception and throws. Within the coroutine, consider either:
Initiating the asynchronous operation with a handler of
context[error_code]
, causing theyield_context
to populate the providedboost::system::error_code
on failure rather than throwing.boost::system::error_code error;
timer_.async_wait(context[error]); // On failure, populate error.Catch the
system_error
and suppress it.
On failure Boost.Asio will populate a boost::system::error_code
if the application is capable of receiving it, otherwise it will throw an exception. This pattern can be observed throughout Boost.Asio:
- All asynchronous operation handler's accept an lvalue
const boost::system::error_code
as their first parameter. Hence, the initiating function should not throw, as the application will be informed of the error within the handler. This is not always apparent when using functors that discards extra arguments, such asboost::bind
. - Synchronous operations are overloaded to support throwing and non-throwing versions. For example,
timer.cancel()
will throw on failure, where astimer.cancel(boost::system::error_code&)
will set theerror_code
to indicate the error. - As noted above, when an asynchronous operation fails within a stackful coroutine and the
yield_context
handler is not provided aboost::system::error_code
, then asystem_error
exception will be thrown. - When using futures, if the asynchronous operation fails, then the
error_code
is converted into asystem_error
exception and passed back to the caller through thefuture
.
Here is a complete minimal example based on the original problem that runs to completion.
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
int main()
{
boost::asio::io_service io_service;
boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::pos_infin);
boost::asio::spawn(io_service,
[&](boost::asio::yield_context yield)
{
// As only one thread is processing the io_service, the posted
// timer cancel will only be invoked once the coroutine yields.
io_service.post([&](){ timer.cancel(); });
// Initiate an asynchronous operation, suspending the current coroutine,
// and allowing the io_service to process other work (i.e. cancel the
// timer). When the timer is cancelled, the asynchronous operation is
// completed with an error, causing the coroutine to resume. As an
// error_code is provided, the operation will not throw on failure.
boost::system::error_code error;
timer.async_wait(yield[error]);
assert(error == boost::asio::error::operation_aborted);
});
io_service.run();
}
XMPP library working with Boost.ASIO
According some fragments of source code, Swiften uses Boost internally, but not ASIO part of it. It uses things like shared_ptr
, boost::bind
, random generator and so on, but not the boost::asio
.
And according to sources, Swift::EventLoop
has io_service
-like interface, but not use it.
So the answer is: no, you cannot extract io_service
from Swiften since it do not use boost::asio.
UPD: But, you can use Swiften in separate thread in async manner and then do io_service::post
to your own eventloop, but need to write our own wrapper, completion handlers and so on to manage this.
Related Topics
Compiling with G++ Using Multiple Cores
How to Print to Console When Using Qt
Compare Double to Zero Using Epsilon
Visual C++ 2008 Express Download Link Dead
The New Keyword "Auto"; When Should It Be Used to Declare a Variable Type
What Exactly Is Streambuf? How to Use It
Easy Rule to Read Complicated Const Declarations
How to Convert from Int to Char*
Why Do We Require Requires Requires
C++11 Member Initializer List VS In-Class Initializer
Returning a Const Reference to an Object Instead of a Copy
Why Would I Prefer Using Vector to Deque
How to Implement a BéZier Curve in C++
How to Check That an Element Is in a Std::Set
Differencebetween Exit() and Abort()