Can i have boost asio socket references in two different class instances? - c++

I want to std::move(my_asio_socket) to the instance of some class. What if I do the same for an instance of some other class?
My purpose is to read_async in one class instance (let's say class A), and to execute write_async in the other (let's say class B). Because of some functionality implementations, I should do it this way.
Any suggestion would be nice.
UPDATED
it's not working properly as i expected.
The VS2015(vc14 compiler) shows me a kind of exception while debugging:
Microsoft C++ exception: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> > at memory location 0x02D8E3BC.
And after i hit continue in VS it show me that:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
As i said, i'm trying to boost::move (or std::move) the socket to other class instance. Here is a snippet of code of what i'm doing:
boost::shared_ptr<connection> new_connection_;//it's a field in my class,
//that's why i should reset it later
new_connection_.reset(new connection(std::move(socket_), io_service_));
new_connection_->start();
Now here is my connection ctor:
connection::connection(boost::asio::ip::tcp::socket sock, boost::asio::io_service& io_ptr)
: socket_(boost::move(sock)),
io_ptr_(io_ptr),
remote_ep(socket_.remote_endpoint()),
//request_handler_(new request_handler(boost::move(socket_))),
work(new boost::asio::io_service::work(io_ptr))
{
boost::shared_ptr<request_handler> req_ptr(new request_handler(boost::move(socket_)));
request_handler_.swap(req_ptr);
}
As you can see, i've tried initializing in the commented line, but it shows me the same result.
Here is the ctor for request_handler:
request_handler::request_handler(boost::asio::ip::tcp::socket sock):
socket_(boost::move(sock)){ }
And here is my method connection::start where the problem detects:
void connection::start()
{
boost::asio::ip::tcp::socket::keep_alive kl(true);
boost::asio::ip::tcp::socket::enable_connection_aborted eca(true);
// here it breaks, when trying to set an option
socket_.set_option(eca);
socket_.set_option(kl);
socket_.async_read_some(boost::asio::buffer(buffer_),
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
This problem appears only when i use to move socket into the new instance of request_handler. If i'm not - then all goes okey. I can't understand what reason it could be, but seems like my socket_ (i declare it everywhere without any & or *) field from connection class is lost or kind of. But the debugger isn't showing me smthing like null, so i don't know what is it.

In general it is not guaranteed:
Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, move-assigning from a std::string or from a std::vector may result in the argument being left empty. However, this behaviour should not be relied upon.
But according to the documentation for tcp::socket it is left in the same state:
Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(io_service&) constructor.

Related

boost::asio::io_service check if null

I am using boost 1.55 (io_service doc). I need to call the destructor on my io_service to reset it after power is cycled on my serial device to get new data. The problem is that when the destructor is called twice (re-trying connection), I get a segmentation fault.
In header file
boost::asio::io_service io_service_port_1;
In function that closes connection
io_service_port_1.stop();
io_service_port_1.reset();
io_service_port_1.~io_service(); // how to check for NULL?
// do I need to re-construct it?
The following does not work:
if (io_service_port_1)
if (io_service_port_1 == NULL)
Thank you.
If you need manual control over when the object is created and destroyed, you should be wrapping it in a std::unique_ptr object.
std::unique_ptr<boost::asio::io_service> service_ptr =
std::make_unique<boost::asio::io_service>();
/*Do stuff until connection needs to be reset*/
service_ptr->stop();
//I don't know your specific use case, but the call to io_service's member function reset is probably unnecessary.
//service_ptr->reset();
service_ptr.reset();//"reset" is a member function of unique_ptr, will delete object.
/*For your later check*/
if(service_ptr) //returns true if a valid object exists in the pointer
if(!service_ptr) //returns true if no object is being pointed to.
Generally speaking, you should never directly call ~object_name();. Ever. Ever. Ever. There's several reasons why:
As a normal part of Stack Unwinding, this will get called anyways when the method returns.
deleteing a pointer will call it.
"Smart Pointers" (like std::unique_ptr and std::shared_ptr) will call it when they self-destruct.
Directly calling ~object_name(); should only ever be done in rare cases, usually involving Allocators, and even then, there are usually cleaner solutions.

C++ shared_ptr shared_from_this throws a bad_weak_ptr exception, even though I have a reference to it

EDIT: I never figured this out - I refactored the code to be pretty much identical to a Boost sample, and still had the problem. If anyone else has this problem, yours may be the more common shared_from_this() being called when no shared_ptr exists (or in the constructor). Otherwise, I recommend just rebuilding from the boost asio samples.
I'm trying to do something that I think is pretty common, but I am having some issues.
I'm using boost asio, and trying to create a TCP server. I accept connections with async_accept, and I create shared pointers. I have a long lived object (like a connection manager), that inserts the shared_ptr into a set. Here is a snippet:
std::shared_ptr<WebsocketClient> ptr = std::make_shared<WebsocketClient>(std::move(s));
directory.addPending(ptr);
ptr->onConnect(std::bind(&Directory::addClient, &directory, std::placeholders::_1));
ptr->onDisconnect(std::bind(&Directory::removeClient, &directory, std::placeholders::_1));
ptr->onMessage(std::bind(&Directory::onMessage, &directory, std::placeholders::_1, std::placeholders::_2));
ptr->start();
The Directory has std::set<std::shared_ptr<WebsocketClient>> pendingClients;
The function for adding a client is:
void Directory::addPending(std::shared_ptr<WebsocketClient> ptr){
std::cout << "Added pending client: " << ptr->getName() << std::endl;
pendingClients.insert(ptr);
}
Now, when the WebsocketClient starts, it tries to create a shared_ptr using shared_from_this() and then initiates an async_read_until ("\r\n\r\n"), and passes that shared_ptr to the lambda to keep ownership. It crashes before actually invoking the asio function, on shared_from_this().
Call stack looks like this:
server.exe!WebsocketClient::start()
server.exe!Server::acceptConnection::__l2::<lambda>(boost::system::error_code ec)
server.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> >(boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> & function, ...)
server.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,void <lambda>(boost::system::error_code) ::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned __int64 __formal) Line 142 C++
server.exe!boost::asio::detail::win_iocp_io_service::do_one(bool ec, boost::system::error_code &)
server.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec)
server.exe!Server::run()
server.exe!main(int argc, char * * argv)
However, I get a bad_weak_ptr when I call shared_from_this. I thought that was thrown when no shared_ptr owned this object, but when I call the addPending, I insert "ptr" into a set, so there should still be a reference to it.
Any ideas? If you need more details please ask, and I'll provide them. This is my first post on StackOverflow, so let me know what I can improve.
You could be dealing with memory corruption. Whether that's the case or not, there are some troubleshooting steps you should definitely take:
Log the pointer value returned from make_shared, and again inside the member function just before calling shared_from_this. Check whether that pointer value exists in your running object table (which is effectively what that set<shared_ptr<...>> is)
Instrument constructor and destructor. If the shared_ptr count does actually hit zero, it'll call your destructor and the call stack will give you information on the problem.
If that doesn't help, the fact that you're using make_shared should be useful, because it guarantees that the metadata block is right next to the object.
Use memcpy to dump the raw bytes preceding your object at various times and watch for potential corruption.
Much of this logging will happen in a context that's exhibiting undefined behavior. If the compiler figures out that you're testing for something that's not supposed to be possible, it might actually remove the test. In that case, you can usually manage to make the tests work anyway by precision use of #pragma to disable optimization just on your debug logging code -- you don't want to change optimization settings on the rest of the code, because that might change the way corruption manifests without actually fixing it.
It is difficult to determine the cause of the problem without a code.
But which enable_shared_from_this you use, boost or std?
I see you use std::make_shared, so if WebsocketClient inherits boost::enable_shared_from_this it can cause crash.

C++ asynchronous call best practice

I'm working with boost::asio. I wrote a class responsible for asynchronous reading from socket.
In my application io_service can be stopped and started many times during one application run.
So I have to worry about memory leakage when service is stopped.
I came to two solutions:
A class asking for asynchronous request provides function with a buffer for using in asio reads, and it is responsible for its freeing. This is an obvious solution but I don't like it. Passing a parameter you don't need to a function looks realy strange.
Smart pointer binded to a callback. Example here:
http://pastebin.com/p8nQ5NFi
Now I'm using the second solution but however I'm feeling, I'm inventing a wheel. What's a common practice for buffer cleanage in asynchronous call? Are there any hidden problems in my aproach?
The shared_ptr approach is fairly common. However, instead of passing a shared_ptr as an additional argument to bind, it is possible to pass the shared_ptr as the instance object in place of this.
boost::shared_ptr< my_class > ptr( this );
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, ptr,
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
Often, since the instance is going to be managed via a shared_ptr, which may or may not be in the context of this, it is a good idea to use Boost.SmartPointer's enable_shared_from_this. When a class inherits from boost::enable_shared_from_this, it provides a shared_from_this() member function that returns a valid shared_ptr instance to this.
class my_class: public boost::enable_shared_from_this< my_class >
{
void read()
{
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, shared_from_this(),
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
}
};
boost::shared_ptr< my_class > foo( new my_class() );
foo->read();
In this snippet, foo.get() and foo->shared_from_this() both point to the same instance. This helps prevent difficult to locate memory leaks. For example, in the original example code, a memory leak occurs in Protocol::AsyncReadMessage if AsyncReadHandler's copy-constructor throws when trying to invoke AsyncReadMessage. Boost.Asio's asynchronous TCP daytime server and many of the examples show enable_shared_from_this being used within Boost.Asio. For a deeper understanding, this question specifically covers asynchronous Boost.Asio functions and shared_ptr.
Also, in the original code, it may be easier to make Protocol::AsyncHelper a template class instead of having it be a non-templated class with template member functions. This would allow the AsyncHelper to accept the protocol, stream, and handler as constructor arguments, storing them as member variables. Additionally, it makes the bind calls slightly easier to read since it reduces the amount of arguments needing to be passed and since the member functions are no longer templates, there is no need to specify their full type. Here is a quick pass at an example.

boost::asio async_read doesn't receive data or doesn't use callback

I am trying to receive data from a server application using boost asio's async_read() free function, but the callback I set for when the receiving is never called.
The client code is like this:
Client::Client()
{
m_oIoService.run(); // member boost::asio::io_service
m_pSocket = new boost::asio::ip::tcp::socket(m_oIoService);
// Connection to the server
[...]
// First read
boost::asio::async_read(*m_pSocket,
boost::asio::buffer((void*)&m_oData, sizeof(m_oData)),
boost::bind(&Client::handleReceivedData, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
I tried with small data (a short string) and I can't get it to work. When I use the synchronous read function (boost::asio::read()) using the two same first parameters, everything works perfectly.
Am I missing something with the use of the io_service? I am still unsure about how it works.
boost::asio::service::run () is a blocking call. Now, in your example it may or may not return immediately. In case it doesn't, you you are blocked even before you create a socket, and never call read, so cannot expect a callback. Otherwise, dispatch loop is exited, so no callbacks are ever delivered.
Read more about boost::asio::service::run (). I recommend you check out documentation including tutorial, examples and reference. It is worth going trough it in full to understand the concept.
Hope it helps!
P.S.: On a side note, your code is not exception safe. Beware that if constructor of the class fails with exception then destructor of that class instance is never called. Thus, you may leak at least m_pSocket if its type is not one of the "smart pointers". You should consider making it exception safe, moving the code to another method that should be called by user, or even wrapping this functionality with a free function.

Network connection setup in constructor: good or bad?

I'm working on a class that handles interaction with a remote process that may or may not be available; indeed in most cases it won't be. If it's not, an object of that class has no purpose in life and needs to go away.
Is it less ugly to:
Handle connection setup in the constructor, throwing an exception if the process isn't there.
Handle connection setup in a separate connect() method, returning an error code if the process isn't there.
In option 1), the calling code will of course have to wrap its instantiation of that class and everything else that deals with it in a try() block. In option 2, it can simply check the return value from connect(), and return (destroying the object) if it failed, but it's less RAII-compliant,
Relatedly, if I go with option 1), is it better to throw one of the std::exception classes, derive my own exception class therefrom, roll my own underived exception class, or just throw a string? I'd like to include some indication of the failure, which seems to rule out the first of these.
Edited to clarify: The remote process is on the same machine, so it's pretty unlikely that the ::connect() call will block.
I consider it bad to do a blocking connect() in a constructor, because the blocking nature is not something one typically expects from constructing an object. So, users of your class may be confused by this functionality.
As for exceptions, I think it is generally best (but also the most work) to derive a new class from std::exception. This allows the catcher to perform an action for that specific type of exception with a catch (const myexception &e) {...} statement, and also do one thing for all exceptions with a catch (const std::exception &e) {...}.
See related question: How much work should be done in a constructor?
Regarding throwing exceptions, its perfectly fine to create your own classes. As a hypothetical user I'd prefer if they derived from std::exception, or perhaps std::runtime_error (which allows you to pass an error string to the ctor).
Users who want to can catch your derived type, but the common idiom of:
try {
operation_that_might_throw ();
} catch (std::exception& e) {
cerr << "Caught exception: " << e.what() << endl;
}
will work for your new exception types as well as anything thrown by the C++ runtime. This is basically the Rule of Least Surprise.
If your connection object is effectively non-functional if the connection fails then it doesn't make sense to have the object exist if all its other methods will always do nothing or throw exceptions. For this reason I would perform the connect in a constructor and fail by throwing an exception (derived from std::exception) if this method fails.
However, you are right that clients of the class may need to be aware that the constructor might block or fail. For this reason I might choose to make the constructor private and use a static factory method (named constructor idiom) so that clients have to make an explicit MakeConnection call.
It is still the client's responsibility to determine if not having a connection is fatal to it, or whether it can handle an offline mode. In the former case it can own a connection by value and let any connection failure propogate to its clients; in the latter it can own the object via a pointer, preferably 'smart'. In the latter case it might choose to attempt construction of the owned connection in its constructor or it might defer it until needed.
E.g. (warning: code all completely untested)
class Connection
{
Connection(); // Actually make the connection, may throw
// ...
public:
static Connection MakeConnection() { return Connection(); }
// ...
};
Here's a class that requires a working connection.
class MustHaveConnection
{
public:
// You can't create a MustHaveConnection if `MakeConnection` fails
MustHaveConnection()
: _connection(Connection::MakeConnection())
{
}
private:
Connection _connection;
};
Here's a class that can work without one.
class OptionalConnection
{
public:
// You can create a OptionalConnectionif `MakeConnection` fails
// 'offline' mode can be determined by whether _connection is NULL
OptionalConnection()
{
try
{
_connection.reset(new Connection(Connection::MakeConnection()));
}
catch (const std::exception&)
{
// Failure *is* an option, it would be better to capture a more
// specific exception if possible.
}
}
OptionalConnection(const OptionalConnection&);
OptionalConnection& operator=(const OptionalConnection&);
private:
std::auto_ptr<Connection> _connection;
}
And finally one that creates one on demand, and propogates exceptions to the caller.
class OnDemandConnection
{
public:
OnDemandConnection()
{
}
OnDemandConnection(const OnDemandConnection&);
OnDemandConnection& operator=(const OnDemandConnection&);
// Propgates exceptions to caller
void UseConnection()
{
if (_connection.get() == NULL)
_connection.reset(new Connection(Connection::MakeConnection()));
// do something with _connection
}
private:
std::auto_ptr<Connection> _connection;
}
Don't connect from the constructor, a constructor that blocks is unexpected and bad API design.
Write a connect method and mark your class noncopyable. If you rely on instances being connected already, make the constructor private and write a static factory method to get pre-connected instances.
If the connection would take a long time, it is more reasonable to put the code in another method. Still, you can (and you should) use exceptions to inform the caller whether your connect() method has been successful or not, instead of returning error codes.
It is also more advisable to create a new exception class derived from std::exception instead of throwing plain data or even throwing other STL exceptions. You may also derive your exception class from a more specific description of your error (for example, deriving from std::runtime_error), but this approach is less common.
I think Option 1 is a better approach but you need to think how would you expect the consumer of the class to use this? Just the fact that they have wired it up is good enough to go ahead and connect (Option 1) or the fact they should have the option to call Connect() when they are good and ready (Option 2)?
RAII also supports the DRY principle (don't repeat yourself). However with Option 1 you need to ensure you Exception handling is spot on and you don't get into race conditions. As you know, if there is an exception thrown in the constructor the destructor wont be called to clean up. Also be vary of any static functions you might have as you will need locks around those as well - leading you down a spiral path.
If you haven't seen this post yet its a good read.
I would go with the second one, since I believe that the constructor should not do any other thing than initialize the private members. Besides that, it's easier to deal with failures (such as not connecting). Depending on what you're exactly going to do, you could keep the object alive and call the connect method when you need it, minimizing the need of creating another object.
As for the exceptions, you should create your own. This will allow the caller to take specific rollback actions when needed.
Under the RAII mind of thought, isn't this by definition good? Acquisation is Initialization.
Another thing that was unclear in my original post is that the client code doesn't have any interaction with this object once it's connected. The client runs in its own thread, and once the object is instantiated and connected, the client calls one method on it that runs for the duration of the parent process. Once that process ends (for whatever reason), the object disconnects and the client thread exits. If the remote process wasn't available, the thread exits immediately. So having a non-connected object lying around isn't really an issue.
I found another reason not to do the connection in the constructor: it means that I either have to handle teardown in the destructor, or have a separate disconnect() call with no separate connect() call, which smells funny. The teardown is non-trivial and might block or throw, so doing it in the destructor is probably less than ideal.
I believe there is a pattern we can use here that addresses some of the points made in other answers. The question is pretty old but this was my first google result.
If the class is useless without a connection, then instantiating it conceptually appears to be half true. The object is not really ready to be used.
The user needs to separately call a connect() method. This just feels like bureaucracy.
Conversely, it is also true that a blocking operation is unconventional, and as other answers point out, may cause confusion. Not to mention annoyances in unit testing and threading.
I believe the pattern for this that addresses our problems is:
We can separate our functionality into more classes. The ready-to-go connection, the class that uses the connection and a factory.
The constructor needs the connection because it can't work without it.
Use a factory that sets up the connection to save the caller some work.
Our factory can be instantiated as empty (which makes sense). Then we can retrieve our class using it.
For example an FTPServer (not in C++ sorry)
class FTPServerFactory:
def get_with_environ_variables() -> FTPServer:
# create your connection here e.g. with FTP login details
class FTPServer:
def __init__(ftp_host: FTP_Host): #logged in an ready to go
There are two distinct benefits of this
Testing - we can easily mock a logged-in ftp_host to return whatever we want. This is way less confusing than having to reach into the class's constructor or the connect() method. We won't need to
Defining different ways of connecting using methods e.g. with env variables or user input