Discussion:
[asio-users] boost::asio::windows::object_handle and ownership
Valentyn Pavliuchenko
2015-09-06 16:31:00 UTC
Permalink
Hello,

I'm trying to use io_service to build a replacement of Windows
::WaitForMultipleObjects event loop in my application. The reason is simple
- I want to use asio networking, but don't want to create an extra thread
for that. So I'm uniting all in io_service by utilizing
boost::asio::windows::object_handle to wrap HANDLEs from existing codebase.

And I have a problem here:

asio::windows::object_handle does take ownership of the HANDLE passed to
it. I.e. it closes a handle in destructor and there's no way to prevent
this. In my case, I already have a quite big application written in a way
that it manages HANDLE ownership by itself, so ownership is a problem.

How about adding a method like "detach()" to asio::windows::basic_handle?
This method can make object to forget about a HANDLE, i.e. return object
into a default-constructed state. I believe this functionality will be
useful for other users as well.

If the idea is acceptable, I can provide a patch.


Best regards,
Valentyn Pavliuchenko
Bjorn Reese
2015-09-06 17:28:14 UTC
Permalink
On 09/06/2015 06:31 PM, Valentyn Pavliuchenko wrote:

> asio::windows::object_handle does take ownership of the HANDLE passed to
> it. I.e. it closes a handle in destructor and there's no way to prevent
> this. In my case, I already have a quite big application written in a
> way that it manages HANDLE ownership by itself, so ownership is a problem.

A workaround is to pass a service with an empty destroy() member to
your socket/handle.

I have not tried it with asio::windows::object_handler, but here is an
example using asio::posix::stream_descriptor:

https://github.com/breese/aware/blob/master/include/aware/detail/native_socket.hpp
Igor R
2015-09-06 17:54:52 UTC
Permalink
>
> I'm trying to use io_service to build a replacement of Windows
> ::WaitForMultipleObjects event loop in my application. The reason is simple
> - I want to use asio networking, but don't want to create an extra thread
> for that. So I'm uniting all in io_service by utilizing
> boost::asio::windows::object_handle to wrap HANDLEs from existing codebase.
>
> And I have a problem here:
>
> asio::windows::object_handle does take ownership of the HANDLE passed to
> it. I.e. it closes a handle in destructor and there's no way to prevent
> this. In my case, I already have a quite big application written in a way
> that it manages HANDLE ownership by itself, so ownership is a problem.
>
> How about adding a method like "detach()" to asio::windows::basic_handle?
> This method can make object to forget about a HANDLE, i.e. return object
> into a default-constructed state. I believe this functionality will be
> useful for other users as well.
>
> If the idea is acceptable, I can provide a patch.
>



Note that asio socket can also be created (or assign()'ed) from a native
handle. So if your idea gets accepted, it probably should be applied to the
sockets as well.
Actually, if we take a look at a wider context, a similar "detaching"
feature could exist in every raii-style object (eg. in smart pointers). Why
doesn't it? Perhaps because it would encourage the error-prone design,
where a part of code use raii while another one owns the resource
"manually".
Valentyn Pavliuchenko
2015-09-06 18:07:10 UTC
Permalink
On Sun, Sep 6, 2015 at 8:54 PM, Igor R <***@gmail.com> wrote:

>
> Actually, if we take a look at a wider context, a similar "detaching"
> feature could exist in every raii-style object (eg. in smart pointers). Why
> doesn't it? Perhaps because it would encourage the error-prone design,
> where a part of code use raii while another one owns the resource
> "manually".
>

I would disagree here. RAII smart pointers are just an alternative to
manual memory management. Here, object_handle takes ownership without any
alternatives provided. In my particular case, I already have a RAII object
managing a HANDLE - that's why I don't need object_handle to do the same.

--
Best regards,
Valentyn Pavliuchenko
Valentyn Pavliuchenko
2015-09-06 18:22:26 UTC
Permalink
Checked few options:
- empty destroy() - won't work, since destroy actually does unregister
handle from a thread pool - this piece of functionality is needed
- DuplicateHandle - looks like working for simple cases, but is definitely
not universal: MSDN says to not use it for socket handles (and I have
some). Yes, it's possible to convert all sockets to use asio, but in
generic case DuplicateHandle is not a solution.

--
Best regards,
Valentyn Pavliuchenko

On Sun, Sep 6, 2015 at 9:07 PM, Valentyn Pavliuchenko <
***@gmail.com> wrote:

> On Sun, Sep 6, 2015 at 8:54 PM, Igor R <***@gmail.com> wrote:
>
>>
>> Actually, if we take a look at a wider context, a similar "detaching"
>> feature could exist in every raii-style object (eg. in smart pointers). Why
>> doesn't it? Perhaps because it would encourage the error-prone design,
>> where a part of code use raii while another one owns the resource
>> "manually".
>>
>
> I would disagree here. RAII smart pointers are just an alternative to
> manual memory management. Here, object_handle takes ownership without any
> alternatives provided. In my particular case, I already have a RAII object
> managing a HANDLE - that's why I don't need object_handle to do the same.
>
> --
> Best regards,
> Valentyn Pavliuchenko
>
>
>
Scott Mueller
2015-09-06 20:43:37 UTC
Permalink
You could use WSADuplicateSocket for socket usage.

Best Regards,

M. Scott Mueller

On Sep 6, 2015, at 11:24 AM, Valentyn Pavliuchenko <***@gmail.com<mailto:***@gmail.com>> wrote:

Checked few options:
- empty destroy() - won't work, since destroy actually does unregister handle from a thread pool - this piece of functionality is needed
- DuplicateHandle - looks like working for simple cases, but is definitely not universal: MSDN says to not use it for socket handles (and I have some). Yes, it's possible to convert all sockets to use asio, but in generic case DuplicateHandle is not a solution.

--
Best regards,
Valentyn Pavliuchenko

On Sun, Sep 6, 2015 at 9:07 PM, Valentyn Pavliuchenko <***@gmail.com<mailto:***@gmail.com>> wrote:
On Sun, Sep 6, 2015 at 8:54 PM, Igor R <***@gmail.com<mailto:***@gmail.com>> wrote:

Actually, if we take a look at a wider context, a similar "detaching" feature could exist in every raii-style object (eg. in smart pointers). Why doesn't it? Perhaps because it would encourage the error-prone design, where a part of code use raii while another one owns the resource "manually".

I would disagree here. RAII smart pointers are just an alternative to manual memory management. Here, object_handle takes ownership without any alternatives provided. In my particular case, I already have a RAII object managing a HANDLE - that's why I don't need object_handle to do the same.

--
Best regards,
Valentyn Pavliuchenko
Valentyn Pavliuchenko
2015-09-07 12:40:16 UTC
Permalink
Yes, WSADuplicateSocket does the job. I can get the workaround with such
duplicate approach, even more - I already have that working. But I'd like
asio to provide a non-owning object_handle in whatever way (could be a
separate object_handle_reference class, or any other design approach), so
that no workarounds are needed in future. And I can write a code if the
idea is accepted.

--
Best regards,
Valentyn Pavliuchenko

On Sun, Sep 6, 2015 at 11:43 PM, Scott Mueller <***@osisoft.com> wrote:

> You could use WSADuplicateSocket for socket usage.
>
> Best Regards,
>
> M. Scott Mueller
>
> On Sep 6, 2015, at 11:24 AM, Valentyn Pavliuchenko <
> ***@gmail.com> wrote:
>
Scott Mueller
2015-09-06 17:25:28 UTC
Permalink
Why not use ::DuplicateHandle? I used this technique to make a named pipe server so that I could use ::ConnectNamedPipe and use the asynch_wait on a duplicate handle placed in an object_handle.

Best Regards,

M. Scott Mueller

> On Sep 6, 2015, at 9:33 AM, Valentyn Pavliuchenko <***@gmail.com> wrote:
>
> Hello,
>
> I'm trying to use io_service to build a replacement of Windows ::WaitForMultipleObjects event loop in my application. The reason is simple - I want to use asio networking, but don't want to create an extra thread for that. So I'm uniting all in io_service by utilizing boost::asio::windows::object_handle to wrap HANDLEs from existing codebase.
>
> And I have a problem here:
>
> asio::windows::object_handle does take ownership of the HANDLE passed to it. I.e. it closes a handle in destructor and there's no way to prevent this. In my case, I already have a quite big application written in a way that it manages HANDLE ownership by itself, so ownership is a problem.
>
> How about adding a method like "detach()" to asio::windows::basic_handle? This method can make object to forget about a HANDLE, i.e. return object into a default-constructed state. I believe this functionality will be useful for other users as well.
>
> If the idea is acceptable, I can provide a patch.
>
>
> Best regards,
> Valentyn Pavliuchenko
> ------------------------------------------------------------------------------
> _______________________________________________
> asio-users mailing list
> asio-***@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/asio-users
> _______________________________________________
> Using Asio? List your project at
> http://think-async.com/Asio/WhoIsUsingAsio
Loading...