
Hello! I have a small library that is intended for convenient and declarative resource wrappers creation. Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html Main Page: http://rain.ifmo.ru/~sorokin/rcpp/ Although this library is small I think it is useful. I think it is possible to use it in implementations of asio, filesystem and thread. **-- Ivan Sorokin

Ivan Sorokin wrote:
Hello!
I have a small library that is intended for convenient and declarative resource wrappers creation.
Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html
Main Page: http://rain.ifmo.ru/~sorokin/rcpp/
Although this library is small I think it is useful. I think it is possible to use it in implementations of asio, filesystem and thread.
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. Also it seems your implementation doesn't support throwing move constructors.

Hello. Thanks for feedback, Mathias! Mathias Gaunard wrote:
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. There is no such library Boost.Move. Do you mean to implement move like Boost.Thread does? If so. I think it is not necessary because one can just write "underlying_resource_type" instead of "thread_move_t" and ".release()" instead ".move()".
Also it seems your implementation doesn't support throwing move constructors. If copy constructor or move constructor can throw an exception the only function that works incorrect is release. There is no way to implement it in exception safe manner in this case.
Note that usually this is not a problem. Usually underlying_resource_type is not something complex, but rather it is just int or void* or something like that. So its copy and move constructors do not throw exceptions.

Hi, ----- Original Message ----- From: "Ivan Sorokin" <sorokin@rain.ifmo.ru> To: <boost@lists.boost.org> Sent: Monday, February 22, 2010 5:56 PM Subject: Re: [boost] [rfc] rcpp
Hello.
Thanks for feedback, Mathias!
Mathias Gaunard wrote:
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. There is no such library Boost.Move.
Please see on the review schedule for Boost.Move http://www.boost.org/community/review_schedule.html I thinnk that we should say instead Toward Boost.Move library, so anyone will know that we are talking of a library that it is not yet in Boost but that pretend to be in. Best, Vicente

Ivan Sorokin wrote:
Hello.
Thanks for feedback, Mathias!
Mathias Gaunard wrote:
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. There is no such library Boost.Move.
It is in the review queue to be included as a first-class Boost citizen, but it seems it is already used by Boost.Interprocess and shipped with it.
If copy constructor or move constructor can throw an exception the only function that works incorrect is release.
My bad, I assumed the operator= was implemented as you described in the documentation (clear current resource first), but you're actually using a temporary then swap, which means the new resource is moved *before* the old resource is released.

Mathias Gaunard wrote:
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. There is no such library Boost.Move. It is in the review queue to be included as a first-class Boost citizen, but it seems it is already used by Boost.Interprocess and shipped with it.
I've implemented my library over Boost.Move: http://rain.ifmo.ru/~sorokin/rcpp/boost_move.diff I have three questions. 1 Is it possible to specialize is_movable<T> for primitive types (e.g. int, void*, etc) to return true? 2 Did I properly specialize has_nothrow_move? 3 When will Boost.Move become a part of boost?

Ivan Sorokin wrote:
Mathias Gaunard wrote:
You might want to use proper move emulation in the absence of C++0x, as is provided by Boost.Move. There is no such library Boost.Move. It is in the review queue to be included as a first-class Boost citizen, but it seems it is already used by Boost.Interprocess and shipped with it.
I've implemented my library over Boost.Move: http://rain.ifmo.ru/~sorokin/rcpp/boost_move.diff
I have three questions.
1 Is it possible to specialize is_movable<T> for primitive types (e.g. int, void*, etc) to return true? 2 Did I properly specialize has_nothrow_move?
I think is_movable is supposed to be used to detect whether the type uses Boost.Move. Your specialization of has_nothrow_move appears correct at first glance.
3 When will Boost.Move become a part of boost?
When it gets reviewed. It could be said, however, that the review system in place is extremely slow and that it's going to take years (literally).

What is the safe_bool stuff for; or, why have you implemented `operator sb_type() const` rather than `operator bool() const` for evaluating a `resource` as a `bool`?
I have a small library that is intended for convenient and declarative resource wrappers creation.
Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html
Main Page: http://rain.ifmo.ru/~sorokin/rcpp/

AMDG Daniel Trebbien wrote:
What is the safe_bool stuff for; or, why have you implemented `operator sb_type() const` rather than `operator bool() const` for evaluating a `resource` as a `bool`?
This is a common idiom to prevent problems from the fact that bool can convert to int. In Christ, Steven Watanabe

Daniel Trebbien wrote:
I have a small library that is intended for convenient and declarative resource wrappers creation.
Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html
Main Page: http://rain.ifmo.ru/~sorokin/rcpp/
What is the safe_bool stuff for; or, why have you implemented `operator sb_type() const` rather than `operator bool() const` for evaluating a `resource` as a `bool`?
Consider: struct T { operator bool(); }; void f() { T a, b; a + b; // correct (convert to bool and add) a * b; // as well a / b; a < b; } I want to have possibility to write objects of my class under if and while, but without addition, multiplication, etc So instead of operator bool I use operator to member-function.

I think that this library has potential. Writing resource-managing classes can lead to bugs very easily, so having a generic solution to the problem of creating resource-managing classes is definitely appealing. However, I think that the library can use a little more generality. For example, it would be nice if the resource config had an `is_invalid` member. This would be useful in creating a resource manager for Windows `HANDLE`s that result from calls to `DuplicateHandle`. I need to keep track of the `DuplicateHandle` return value so that I would know whether the `HANDLE` member of the resource manager is set to something that needs to be closed with `CloseHandle`. Essentially the underlying resource type in this case is a pair of a `HANDLE` and `BOOL`, where the "invalid value" is a pair with the `BOOL` set to `FALSE` and an indeterminate value of the `HANDLE`. In order to use the `rcpp::resource` template, I would need to override the `==` operator so that equality of the resource means equality of the `BOOL` member only, which is not ideal. I think that an `is_invalid` member would do the trick rather nicely, however. Also, I think that it would be nice to have a `shared_resource` template. I have an application in mind where I would like to create a shared `HANDLE` that is only closed if it is invalid and all references to it have been destroyed (a shared reference count reaches 0).
Hello!
I have a small library that is intended for convenient and declarative resource wrappers creation.
Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html
Main Page: http://rain.ifmo.ru/~sorokin/rcpp/
Although this library is small I think it is useful. I think it is possible to use it in implementations of asio, filesystem and thread.
**-- Ivan Sorokin _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Daniel Trebbien wrote:
I have a small library that is intended for convenient and declarative resource wrappers creation.
Read Documentation: http://rain.ifmo.ru/~sorokin/rcpp/doc/index.html
Main Page: http://rain.ifmo.ru/~sorokin/rcpp/
For example, it would be nice if the resource config had an `is_invalid` member. I thought about that. And I decided to make library without it because
1 Even if user provides is_invalid() it still needs to provide invalid_value() function. invalid_value() is required by default-constructor, move-constructor/move-assignment-operator and release() function. This is the main cause. 2 It is not really necessary. Let we have some underlying_resource_type for example std::pair<HWND, HDC> (common_dc) We can divide its values into three groups: 1 Valid values (first != NULL && second != NULL) 2 Invalid values ((first == NULL) ^ (second == NULL)) 3 "True" invalid value (first == NULL && second == NULL) When user wants to wrap underlying_resource_type into rcpp::resource, it can check whether underlying_resource is invalid and it is, wraps "True" invalid value. Note that rcpp::resource is not intended to keep every possibly value of underlying_resource_type. It can keep only two kind of values: values that can be disposed or invalid_value. (we can wrap (char *)666 into auto_ptr, but it is not correct, so it is with rcpp::resource)
This would be useful in creating a resource manager for Windows `HANDLE`s that result from calls to `DuplicateHandle`. I need to keep track of the `DuplicateHandle` return value so that I would know whether the `HANDLE` member of the resource manager is set to something that needs to be closed with `CloseHandle`. What kind of HANDLE that can be returned from DuplicateHandle should not be disposed by CloseHandle? Essentially the underlying resource type in this case is a pair of a `HANDLE` and `BOOL`, where the "invalid value" is a pair with the `BOOL` set to `FALSE` and an indeterminate value of the `HANDLE`. In order to use the `rcpp::resource` template, I would need to override the `==` operator so that equality of the resource means equality of the `BOOL` member only, which is not ideal. I think that an `is_invalid` member would do the trick rather nicely, however. Why do not use boost::optional<HANDLE> as underlying resource type? Also, I think that it would be nice to have a `shared_resource` template. I have an application in mind where I would like to create a shared `HANDLE` that is only closed if it is invalid and all references to it have been destroyed (a shared reference count reaches 0). I thought about that. I don't think it has wide application. Moreover it can be emulated with boost::shared_ptr<rcpp::resource>. Is it worth while?

What kind of HANDLE that can be returned from DuplicateHandle should not be disposed by CloseHandle?
The only time I should call `CloseHandle` on the `HANDLE` result from `DuplicateHandle` is if the `DuplicateHandle` call succeeded. This is because the MSDN documentation does not assert that the `HANDLE` resulting from `DuplicateHandle` will never be `NULL` or `INVALID_HANDLE_VALUE`.
Essentially the underlying resource type in this case is a pair of a `HANDLE` and `BOOL`, where the "invalid value" is a pair with the `BOOL` set to `FALSE` and an indeterminate value of the `HANDLE`. In order to use the `rcpp::resource` template, I would need to override the `==` operator so that equality of the resource means equality of the `BOOL` member only, which is not ideal. I think that an `is_invalid` member would do the trick rather nicely, however. Why do not use boost::optional<HANDLE> as underlying resource type?
I hadn't thought of this. Seems like it would work...
Also, I think that it would be nice to have a `shared_resource` template. I have an application in mind where I would like to create a shared `HANDLE` that is only closed if it is invalid and all references to it have been destroyed (a shared reference count reaches 0). I thought about that. I don't think it has wide application. Moreover it can be emulated with boost::shared_ptr<rcpp::resource>. Is it worth while?
I think so because `boost::shared_ptr` adds a level of indirection that is unnecessary.

Daniel Trebbien wrote:
What kind of HANDLE that can be returned from DuplicateHandle should not be disposed by CloseHandle? The only time I should call `CloseHandle` on the `HANDLE` result from `DuplicateHandle` is if the `DuplicateHandle` call succeeded. This is because the MSDN documentation does not assert that the `HANDLE` resulting from `DuplicateHandle` will never be `NULL` or `INVALID_HANDLE_VALUE`.
What do you think about the following functions? rcpp::win::file_handle clone(rcpp::win::file_handle const & f) { HANDLE h; BOOL r = ::DuplicateHandle(GetCurrentProcess(), f.get(), GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS); if (r == FALSE) return rcpp::win::file_handle(); // or throw an exception return rcpp::win::file_handle(h); } rcpp::win::kernel_handle clone(rcpp::win::kernel_handle const & f) { HANDLE h; BOOL r = ::DuplicateHandle(GetCurrentProcess(), f.get(), GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS); if (r == FALSE) return rcpp::win::kernel_handle(); // or throw an exception return rcpp::win::kernel_handle(h); }
Also, I think that it would be nice to have a `shared_resource` template. I have an application in mind where I would like to create a shared `HANDLE` that is only closed if it is invalid and all references to it have been destroyed (a shared reference count reaches 0). I thought about that. I don't think it has wide application. Moreover it can be emulated with boost::shared_ptr<rcpp::resource>. Is it worth while?
I think so because `boost::shared_ptr` adds a level of indirection that is unnecessary.
I think that I can implement shared_resource if I is asked for that.

What do you think about the following functions?
rcpp::win::file_handle clone(rcpp::win::file_handle const & f) { HANDLE h; BOOL r = ::DuplicateHandle(GetCurrentProcess(), f.get(), GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (r == FALSE) return rcpp::win::file_handle(); // or throw an exception
return rcpp::win::file_handle(h); }
rcpp::win::kernel_handle clone(rcpp::win::kernel_handle const & f) { HANDLE h; BOOL r = ::DuplicateHandle(GetCurrentProcess(), f.get(), GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (r == FALSE) return rcpp::win::kernel_handle(); // or throw an exception
return rcpp::win::kernel_handle(h); }
In `clone(rcpp::win::file_handle const &)`, what if `h` is `INVALID_HANDLE_VALUE` and `r` is not `FALSE` (`DuplicateHandle` succeeded, but the resulting `HANDLE` was `INVALID_HANDLE_VALUE`)? Then the function would return an "empty" `rcpp::win::file_handle` and the `INVALID_HANDLE_VALUE` `HANDLE` would never be closed. Similarly, if `DuplicateHandle` could set `h` to `NULL` in `clone(rcpp::win::kernel_handle const &)`, then the `NULL` `HANDLE` would never be closed. I know, you're thinking that this is picky. Yes, it's really picky, but I can't help from thinking about this case, especially because the MSDN documentation does not definitively state that this can not happen. I also looked at the documentation for `CloseHandle` to see if it can not accept `NULL` or `INVALID_HANDLE_VALUE`, but there is nothing on that issue, either. (If `CloseHandle` did not accept `NULL`, for example, then `DuplicateHandle` could never use `NULL` for the resulting `HANDLE` value.) I like the solution that you had, which is to use `boost::optional<HANDLE>` with invalid value `boost::none`.

On Feb 28, 2010, at 6:13 PM, Daniel Trebbien wrote:
[...] I know, you're thinking that this is picky. Yes, it's really picky, but I can't help from thinking about this case, especially because the MSDN documentation does not definitively state that this can not happen. I also looked at the documentation for `CloseHandle` to see if it can not accept `NULL` or `INVALID_HANDLE_VALUE`, but there is nothing on that issue, either. (If `CloseHandle` did not accept `NULL`, for example, then `DuplicateHandle` could never use `NULL` for the resulting `HANDLE` value.)
Calling 'CloseHandle' with a value of NULL or INVALID_HANDLE_VALUE usually simply results in an access violation. You may be able to catch it with SEH but I have never tried... Ciao, Andreas
participants (6)
-
Andreas Masur
-
Daniel Trebbien
-
Ivan Sorokin
-
Mathias Gaunard
-
Steven Watanabe
-
vicente.botet