简体   繁体   English

使用tcp :: acceptor :: async_accept传递所有权的套接字指针

[英]Socket pointer transfer of ownership with tcp::acceptor::async_accept

I've recently started using Boost.Asio in a project and would like to know whether anyone knows a clean solution to transfer ownership of a newly created socket to tcp::acceptor::async_accept, which would in turn transfer this ownership to the accept handler function. 我最近开始在一个项目中使用Boost.Asio,并想知道是否有人知道一个干净的解决方案,将新创建的套接字的所有权转移到tcp :: acceptor :: async_accept,这将依次将此所有权转移到接受处理函数。

This isn't an incoherent desire, mind you, since the handler is to be called exactly once. 请注意,这不是一种不连贯的愿望,因为处理程序只需要调用一次。

I have noticed I can't std::bind() an std::unique_ptr<> as parameter, since std::bind() requires its parameters to be CopyConstructible, and rightfully so. 我注意到我不能std :: bind()一个std :: unique_ptr <>作为参数,因为std :: bind()要求它的参数是CopyConstructible,这是正确的。 Not only that, but Boost's AcceptHandler concept is also required to be CopyConstructible. 不仅如此,Boost的AcceptHandler概念也必须是CopyConstructible。

So my options would be: 所以我的选择是:

  • Go the deprecated std::auto_ptr<> way of moving objects with the copy constructor, potentially causing obscure bugs on new releases of Boost.Asio. 使用复制构造函数移动已弃用的std :: auto_ptr <>方法,可能会在新版本的Boost.Asio上造成模糊的错误。
  • Use std::shared_ptr<> and have no way to take the shared ownership off the pointer once it's not needed anymore, ie when it reaches the actual handler function (this is how the job is done on the examples at http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html as far as I've read). 使用std :: shared_ptr <>并且一旦不再需要它就无法从指针中取出共享所有权,即当它到达实际的处理函数时(这就是http:// www上的示例的工作方式) 据我所知,.boost.org / doc / libs / 1_43_0 / doc / html / boost_asio / examples.html

or 要么

  • You have a better idea for me. 你对我有更好的想法。

I'm pretty much at a loss here. 我在这里几乎不知所措。 Can anyone enlighten me? 任何人都可以开导我吗?

I tried to find a way to do this using the c++0x standard library, but could not. 我试图找到一种方法来使用c ++ 0x标准库,但不能。 Eventually I settled on writing my own rvalue_reference_wrapper and rvalue_ref() convenience class. 最后我决定编写自己的rvalue_reference_wrapper和rvalue_ref()便利类。 As per usual with std::bind, you need to wrap your non copyable object in something that is copyable (reference_wrapper is the best example). 与std :: bind一样,你需要将非可复制对象包装在可复制的东西中(reference_wrapper是最好的例子)。 You could also have just passed a pointer, but that means changing your interface. 您也可以刚刚传递指针,但这意味着更改您的界面。

This worked on my machine: 这适用于我的机器:

#include <iostream>
#include <functional>
#include <memory>

template< class T >
struct rvalue_reference_wrapper
{
    rvalue_reference_wrapper( T&& t )
        : t_(std::move(t))
    {}

    operator T&&() const volatile
    {
        return std::move(t_);
    }

private:
    T&& t_; 
};

template< class T >
rvalue_reference_wrapper<T> rvalue_ref( T&& t )
{
    return rvalue_reference_wrapper<T>(std::move(t));
}

void go( std::unique_ptr<int> i )
{
    std::cout << *i << std::endl;
}

int main()
{
    std::unique_ptr<int> i(new int(1));

    auto b = std::bind( go, rvalue_ref(std::move(i)) );
    //auto b = std::bind( go, std::ref(std::move(i)) ); // Wont work

    b();
}

I have not made the code bulletproof, but welcome some discussion about the need for an rvalue_reference_wrapper, or how to simulate one using std::reference_wrapper. 我没有使代码具有防弹性,但欢迎讨论rvalue_reference_wrapper的需要,或者如何使用std :: reference_wrapper来模拟它。

Also, for your specific case, you will likely need to write a difference version of rvalue_reference_wrapper, which holds the object by value not by rvalue reference, since your original unique_ptr is likely going to leave scope (and be destroyed) since you are using async asio calls. 此外,对于您的特定情况,您可能需要编写rvalue_reference_wrapper的差异版本,该值通过值而非rvalue引用保存对象,因为您的原始unique_ptr可能会因为您使用异步而离开作用域(并被销毁) asio电话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM