# [DICUSS]Cleanup resource handling APIs

- Thread: https://externals.io/message/81546
- Original archive: https://news-web.php.net/php.internals/81546
- Started by Xinchen Hui on 2015-02-02T05:34:51+00:00
- Messages: 19
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #81546 — Xinchen Hui — 2015-02-02T05:34:51+00:00

URL: https://externals.io/message/81546#81546

Hey:

     we used to use lval of zval as a handle to access resource type..

     but now, we introduced a new type IS_RESOURCE, which make the
handle(id) sort of redundant .

     further more, the common usage when handling resource is like:

      if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result,
&offset) == FAILURE) {
        return;
    }
    ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL
result", le_result);

    as you can see, we use "r" to receive a IS_RESOURCE type, that
means, check the type in ZEND_FETCH_RESOURCE is overhead..

   and:

   ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
const char *resource_type_name, int *found_resource_type, int
num_resource_types, ...)

   we use va_args to passing resource type, that means, the rescue
type arguments can not be passed by register but by stack.. which is a
little low effiicient .

   so, I'd like propose a zend_resource handling API cleanup..

   1.  DROP ZEND_REGISTER_RESOURCE/FETCH_RESOURCE.

   2.  add :

       ZEND_API void *zend_fetch_resource(zend_resource *res, const
char *resource_type_name, int resource_type);
ZEND_API void *zend_fetch_resource2(zend_resource *res, const char
*resource_type_name, int *found_type, int resource_type, int
resource_type2);
ZEND_API void *zend_fetch_resource_ex(zval *res, const char
*resource_type_name, int resource_type);
ZEND_API void *zend_fetch_resource2_ex(zval *res, const char
*resource_type_name, int *found_type, int resource_type, int
resource_type2);

   a underworking patch could be found at:
https://github.com/php/php-src/pull/1042

   any ideas & objections?

thanks

-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81547 — Xinchen Hui — 2015-02-02T05:43:04+00:00

URL: https://externals.io/message/81546#81547 · In reply to: #81546

> Hey:
>
>      we used to use lval of zval as a handle to access resource type..
>
>      but now, we introduced a new type IS_RESOURCE, which make the
> handle(id) sort of redundant .
>
>      further more, the common usage when handling resource is like:
>
>       if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result,
> &offset) == FAILURE) {
>         return;
>     }
>     ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL
> result", le_result);
>
>     as you can see, we use "r" to receive a IS_RESOURCE type, that
> means, check the type in ZEND_FETCH_RESOURCE is overhead..
>
>    and:
>
>    ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
>
>    we use va_args to passing resource type, that means, the rescue
> type arguments can not be passed by register but by stack.. which is a
> little low effiicient .
>
>    so, I'd like propose a zend_resource handling API cleanup..
>
>    1.  DROP ZEND_REGISTER_RESOURCE/FETCH_RESOURCE.
>
>    2.  add :
>
>        ZEND_API void *zend_fetch_resource(zend_resource *res, const
> char *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2(zend_resource *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
> ZEND_API void *zend_fetch_resource_ex(zval *res, const char
> *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2_ex(zval *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
>
>    a underworking patch could be found at:
> https://github.com/php/php-src/pull/1042
>
>    any ideas & objections?
furthermore, I'd like to discuss remove the handle in zend_resource struct..

it may breaks some usage (use resource as long/double/string)

   case IS_RESOURCE: {
            char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
            int len;

            len = snprintf(buf, sizeof(buf), "Resource id #"
ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
            return zend_string_init(buf, len, 0);
        }


thanks

>
> thanks
>
> --
> Xinchen Hui
> @Laruence
> http://www.laruence.com/



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81550 — francois@tekwire.net — 2015-02-02T06:51:16+00:00

URL: https://externals.io/message/81546#81550 · In reply to: #81546

> De : Xinchen Hui [mailto:laruence@php.net]
>      we used to use lval of zval as a handle to access resource type..
> 
>      but now, we introduced a new type IS_RESOURCE, which make the
> handle(id) sort of redundant .

Wrong. The IS_RESOURCE type has nothing to do with PHP 7. Only zend_resource is new. And handle is not redundant.

>      further more, the common usage when handling resource is like:
> 
>       if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result,
> &offset) == FAILURE) {
>         return;
>     }
>     ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL
> result", le_result);
> 
>     as you can see, we use "r" to receive a IS_RESOURCE type, that
> means, check the type in ZEND_FETCH_RESOURCE is overhead..

There's no overhead here. Zend_parse_parameters checks that received arg is IS_RESOURCE. Fetch then checks that received resource is one of the accepted resource types. Sorry to say that, but are you sure you understand the difference between zval types and resource types ?

>    ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
> 
>    we use va_args to passing resource type, that means, the rescue
> type arguments can not be passed by register but by stack.. which is a
> little low effiicient .

What do you mean with 'rescue' type ?

Fetch is supposed to check for a variable number of possible resource types. It could probably be restricted to 2 possible types as, generally, it is the maximum (one for non-persistent, one for persistent). But I am not sure the overhead of passing arg on the stack justifies a change. Remember that id is searched in an array, which takes probably much more time that pushing/popping one or two arguments.

>    so, I'd like propose a zend_resource handling API cleanup..
> 
>    1.  DROP ZEND_REGISTER_RESOURCE/FETCH_RESOURCE.
> 
>    2.  add :
> 
>        ZEND_API void *zend_fetch_resource(zend_resource *res, const
> char *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2(zend_resource *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
> ZEND_API void *zend_fetch_resource_ex(zval *res, const char
> *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2_ex(zval *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);

If you drop ZEND_REGISTER_RESOURCE, how do you register new resources ? Or do you mean you don't register them any more ? But registering them is mandatory if we want them to be freed when request ends.

> furthermore, I'd like to discuss remove the handle in zend_resource struct..
>
> it may breaks some usage (use resource as long/double/string)
>
>   case IS_RESOURCE: {
>            char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
>            int len;
>
>            len = snprintf(buf, sizeof(buf), "Resource id #"
>ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
>            return zend_string_init(buf, len, 0);
>        }

OK. You want to remove resource registration. But resources don't work this way (see http://devzone.zend.com/446/extension-writing-part-iii-resources/). If you remove the handle, you remove the whole zend_list API.

The zend_resource struct is not a structure you may fill with random data. Using the handle to store long/double/string is not a legitimate usage.

Regards

François

---

## #81552 — Xinchen Hui — 2015-02-02T07:11:11+00:00

URL: https://externals.io/message/81546#81552 · In reply to: #81550

Hey:


> > […]
>
> Wrong. The IS_RESOURCE type has nothing to do with PHP 7. Only zend_resource is new. And handle is not redundant.
of course it's a typo. I meant zend_resource
>
> > […]
>
> There's no overhead here. Zend_parse_parameters checks that received arg is IS_RESOURCE. Fetch then checks that received resource is one of the accepted resource types. Sorry to say that, but are you sure you understand the difference between zval types and resource types ?
..... do you really read the FETCH_RESOURCE?

ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
const char *resource_type_name, int *found_resource_type, int
num_resource_types, ...)
{
    int actual_resource_type;
//  void *resource;
    va_list resource_types;
    int i;
    zend_resource *res;
    const char *space;
    const char *class_name;

    if (default_id==-1) { /* use id */
        if (!passed_id) {
            if (resource_type_name) {
                class_name = get_active_class_name(&space);
                zend_error(E_WARNING, "%s%s%s(): no %s resource
supplied", class_name, space, get_active_function_name(),
resource_type_name);
            }
            return NULL;
        } else if (Z_TYPE_P(passed_id) != IS_RESOURCE) { // < === what are this?
            if (resource_type_name) {
                class_name = get_active_class_name(&space);
                zend_error(E_WARNING, "%s%s%s(): supplied argument is
not a valid %s resource", class_name, space,
get_active_function_name(), resource_type_name);
            }
            return NULL;
        }


>
> > […]
>
> What do you mean with 'rescue' type ?
expected resource_type
>
> Fetch is supposed to check for a variable number of possible resource types. It could probably be restricted to 2 possible types as, generally, it is the maximum (one for non-persistent, one for persistent). But I am not sure the overhead of passing arg on the stack justifies a change. Remember that id is searched in an array, which takes probably much more time that pushing/popping one or two arguments.
>
> > […]
>
> If you drop ZEND_REGISTER_RESOURCE, how do you register new resources ? Or do you mean you don't register them any more ? But registering them is mandatory if we want them to be freed when request ends.
>
> > […]
>
> OK. You want to remove resource registration. But resources don't work this way (see http://devzone.zend.com/446/extension-writing-part-iii-resources/). If you remove the handle, you remove the whole zend_list API.
>
> The zend_resource struct is not a structure you may fill with random data. Using the handle to store long/double/string is not a legitimate usage.
....I think you don't understand what I am talking about. sorry


thanks
>
> Regards
>
> François
>
>
>
>



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81553 — Xinchen Hui — 2015-02-02T07:18:46+00:00

URL: https://externals.io/message/81546#81553 · In reply to: #81552

Hey:



> Hey:
>
> 
> > […]
> of course it's a typo. I meant zend_resource
> > […]
> ..... do you really read the FETCH_RESOURCE?
>
> ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
> {
>     int actual_resource_type;
> //  void *resource;
>     va_list resource_types;
>     int i;
>     zend_resource *res;
>     const char *space;
>     const char *class_name;
>
>     if (default_id==-1) { /* use id */
>         if (!passed_id) {
>             if (resource_type_name) {
>                 class_name = get_active_class_name(&space);
>                 zend_error(E_WARNING, "%s%s%s(): no %s resource
> supplied", class_name, space, get_active_function_name(),
> resource_type_name);
>             }
>             return NULL;
>         } else if (Z_TYPE_P(passed_id) != IS_RESOURCE) { // < === what are this?
>             if (resource_type_name) {
>                 class_name = get_active_class_name(&space);
>                 zend_error(E_WARNING, "%s%s%s(): supplied argument is
> not a valid %s resource", class_name, space,
> get_active_function_name(), resource_type_name);
>             }
>             return NULL;
>         }
>
>
> > […]
> expected resource_type
> > […]
> ....I think you don't understand what I am talking about. sorry
I think I'd better to explain a bit more.

we used to use handle to lookup a resource in EG(regular_list).. and
store the "int handle" into lval of zval.

but now, we use zend_resource * , which can be directly accessed via
Z_RES_P(zval).

that's why I think the "handle" is a little redundant ..

is that clear?

thanks
>
>
> thanks
> > […]
>
>
>
> --
> Xinchen Hui
> @Laruence
> http://www.laruence.com/



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81555 — Anatol Belski — 2015-02-02T07:35:06+00:00

URL: https://externals.io/message/81546#81555 · In reply to: #81552

Hi,


> Hey:
>
>
> On Mon, Feb 2, 2015 at 2:51 PM, François Laupretre <francois@tekwire.net>
> wrote:
>
> > […]
> of course it's a typo. I meant zend_resource
> > […]
> ..... do you really read the FETCH_RESOURCE?
>
>
> ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...) {
> int actual_resource_type; //  void *resource;
> va_list resource_types; int i; zend_resource *res; const char *space; const
> char *class_name;
>
> if (default_id==-1) { /* use id */ if (!passed_id) { if
> (resource_type_name) {
> class_name = get_active_class_name(&space); zend_error(E_WARNING,
> "%s%s%s(): no %s resource
> supplied", class_name, space, get_active_function_name(),
> resource_type_name); }
> return NULL; } else if (Z_TYPE_P(passed_id) != IS_RESOURCE) { // < === what
> are this? if (resource_type_name) { class_name =
> get_active_class_name(&space); zend_error(E_WARNING, "%s%s%s(): supplied
> argument is not a valid %s resource", class_name, space,
> get_active_function_name(), resource_type_name); }
> return NULL; }
>
>
>
> > […]
> expected resource_type
> > […]
> ....I think you don't understand what I am talking about. sorry
>
>
I was writing about it last year as well
http://marc.info/?l=php-internals&m=142006455308305&w=2 , slightly
different idea. Annd there is also a short piece of code to illustrate:
https://gist.github.com/weltling/9367db5e242ef7e60042 ...

The integer resource looks like is needed at some places, so my suggestion
was to split zend_fetch_resource function like illustrated in the patch.
At 99% of places that integer link is just passed as -1, so then having it
be present always in the signature is just a waste of "resources" :)

Regards

Anatol

---

## #81556 — Xinchen Hui — 2015-02-02T07:40:28+00:00

URL: https://externals.io/message/81546#81556 · In reply to: #81555

Hey:


> Hi,
>
> 
> > […]
> I was writing about it last year as well
> http://marc.info/?l=php-internals&m=142006455308305&w=2 , slightly
> different idea. Annd there is also a short piece of code to illustrate:
> https://gist.github.com/weltling/9367db5e242ef7e60042 ...
>
> The integer resource looks like is needed at some places, so my suggestion
> was to split zend_fetch_resource function like illustrated in the patch.
> At 99% of places that integer link is just passed as -1, so then having it
> be present always in the signature is just a waste of "resources" :)
for now, we still keep the handle which could be accessed by Z_RES_HANDLE_P

I just talked about remove it later maybe.

thanks
>
> Regards
>
> Anatol
>



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81557 — Anatol Belski — 2015-02-02T07:48:59+00:00

URL: https://externals.io/message/81546#81557 · In reply to: #81556

Hi Hui,


> Hey:
>
>
> On Mon, Feb 2, 2015 at 3:35 PM, Anatol Belski <anatol.php@belski.net>
> wrote:
>
> > […]
> for now, we still keep the handle which could be accessed by
> Z_RES_HANDLE_P
>
>
> I just talked about remove it later maybe.
>
>
yeah, I see, u suggest even more so that int thing to be removed from the
struct. But probably one could go this way then - first cleanup the
signature, stabilize. That would give us the ground to localize the
->handle use cases and remove it in the next step. Kind of step by step
doing.

Regards

Anatol

---

## #81558 — Sara Golemon — 2015-02-02T08:01:08+00:00

URL: https://externals.io/message/81546#81558 · In reply to: #81547

> 
> furthermore, I'd like to discuss remove the handle in zend_resource struct..
> 
> it may breaks some usage (use resource as long/double/string

I've seen uses in the wild where file handles are used as array keys (yes, I know, ugly and wrong).

If we were to remove rsrc handle, we should formally deprecate it for at least one minor revision first.

I'm all for killing it, and I fully support improving the internal API, but the gentler we are with BC breaks, the better.

-Sara

---

## #81559 — Wei Dai — 2015-02-02T08:02:29+00:00

URL: https://externals.io/message/81546#81559 · In reply to: #81550

> > […]
>  
>  
> Wrong. The IS_RESOURCE type has nothing to do with PHP 7. Only zend_resource is new. And handle is not redundant.
>  
> > […]
>  
>  
> There's no overhead here. Zend_parse_parameters checks that received arg is IS_RESOURCE. Fetch then checks that received resource is one of the accepted resource types. Sorry to say that, but are you sure you understand the difference between zval types and resource types ?
Are you kidding?  he is one of the main authors of PHP7..  
>  
> > […]
>  
>  
> What do you mean with 'rescue' type ?
>  
> Fetch is supposed to check for a variable number of possible resource types. It could probably be restricted to 2 possible types as, generally, it is the maximum (one for non-persistent, one for persistent). But I am not sure the overhead of passing arg on the stack justifies a change. Remember that id is searched in an array, which takes probably much more time that pushing/popping one or two arguments.
>  
> > […]
>  
>  
> If you drop ZEND_REGISTER_RESOURCE, how do you register new resources ? Or do you mean you don't register them any more ? But registering them is mandatory if we want them to be freed when request ends.
>  
> > […]
>  
>  
> OK. You want to remove resource registration. But resources don't work this way (see http://devzone.zend.com/446/extension-writing-part-iii-resources/). If you remove the handle, you remove the whole zend_list API.
>  
> The zend_resource struct is not a structure you may fill with random data. Using the handle to store long/double/string is not a legitimate usage.
>  
> Regards
>  
> François
>  
>  
>  
>  
>  
> --  
> 
> 
>  
>  

Best,  
Wei Dai

---

## #81560 — Xinchen Hui — 2015-02-02T08:05:44+00:00

URL: https://externals.io/message/81546#81560 · In reply to: #81558

Hey Sara:


>
>
> > […]
>
> I've seen uses in the wild where file handles are used as array keys (yes, I know, ugly and wrong).
>
> If we were to remove rsrc handle, we should formally deprecate it for at least one minor revision first.
>
> I'm all for killing it, and I fully support improving the internal API, but the gentler we are with BC breaks, the better.
I agree, as I said, removing it is the step 2 actions

we may discuss it later..

thanks
>
> -Sara



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81563 — Michael Wallner — 2015-02-02T08:44:52+00:00

URL: https://externals.io/message/81546#81563 · In reply to: #81550

> 

> Sorry to say that, but are you sure you understand the difference between zval types and resource types ?
> 

Thanks, you made my day.

---

## #81564 — Michael Wallner — 2015-02-02T08:47:03+00:00

URL: https://externals.io/message/81546#81564 · In reply to: #81558

> 
> 
> 
> 
> > […]
> 
> I've seen uses in the wild where file handles are used as array keys (yes, I know, ugly and wrong).

Yes, I definitely use that a lot and cannot see why this should be wrong.

> 
> If we were to remove rsrc handle, we should formally deprecate it for at least one minor revision first.
> 
> I'm all for killing it, and I fully support improving the internal API, but the gentler we are with BC breaks, the better.

---

## #81579 — Xinchen Hui — 2015-02-02T10:48:31+00:00

URL: https://externals.io/message/81546#81579 · In reply to: #81546

Hey:

   if no objections, I will commit it.. (no bc breaks, no handle
removing , only APIs change)

   dmitry suggest we change zend_fetch_resource to
zend_verify_resource, I think it make sense.. will do it.


thanks

> Hey:
>
>      we used to use lval of zval as a handle to access resource type..
>
>      but now, we introduced a new type IS_RESOURCE, which make the
> handle(id) sort of redundant .
>
>      further more, the common usage when handling resource is like:
>
>       if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result,
> &offset) == FAILURE) {
>         return;
>     }
>     ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL
> result", le_result);
>
>     as you can see, we use "r" to receive a IS_RESOURCE type, that
> means, check the type in ZEND_FETCH_RESOURCE is overhead..
>
>    and:
>
>    ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
>
>    we use va_args to passing resource type, that means, the rescue
> type arguments can not be passed by register but by stack.. which is a
> little low effiicient .
>
>    so, I'd like propose a zend_resource handling API cleanup..
>
>    1.  DROP ZEND_REGISTER_RESOURCE/FETCH_RESOURCE.
>
>    2.  add :
>
>        ZEND_API void *zend_fetch_resource(zend_resource *res, const
> char *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2(zend_resource *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
> ZEND_API void *zend_fetch_resource_ex(zval *res, const char
> *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2_ex(zval *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
>
>    a underworking patch could be found at:
> https://github.com/php/php-src/pull/1042
>
>    any ideas & objections?
>
> thanks
>
> --
> Xinchen Hui
> @Laruence
> http://www.laruence.com/



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81601 — francois@tekwire.net — 2015-02-02T16:37:34+00:00

URL: https://externals.io/message/81546#81601 · In reply to: #81547

> De : Xinchen Hui [mailto:laruence@php.net]
> furthermore, I'd like to discuss remove the handle in zend_resource struct..
> 
> it may breaks some usage (use resource as long/double/string)
> 
>    case IS_RESOURCE: {
>             char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
>             int len;
> 
>             len = snprintf(buf, sizeof(buf), "Resource id #"
> ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
>             return zend_string_init(buf, len, 0);
>         }

I don't understand how you can delete the resource if you remove the handle from the zend_resource struct. Or would you store the index elsewhere ?

Regards

François

---

## #81757 — Xinchen Hui — 2015-02-04T04:01:56+00:00

URL: https://externals.io/message/81546#81757 · In reply to: #81546

Hey:


> Hey:
>
>      we used to use lval of zval as a handle to access resource type..
>
>      but now, we introduced a new type IS_RESOURCE, which make the
> handle(id) sort of redundant .
>
>      further more, the common usage when handling resource is like:
>
>       if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &result,
> &offset) == FAILURE) {
>         return;
>     }
>     ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL
> result", le_result);
>
>     as you can see, we use "r" to receive a IS_RESOURCE type, that
> means, check the type in ZEND_FETCH_RESOURCE is overhead..
>
>    and:
>
>    ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
>
>    we use va_args to passing resource type, that means, the rescue
> type arguments can not be passed by register but by stack.. which is a
> little low effiicient .
>
>    so, I'd like propose a zend_resource handling API cleanup..
>
>    1.  DROP ZEND_REGISTER_RESOURCE/FETCH_RESOURCE.
>
>    2.  add :
>
>        ZEND_API void *zend_fetch_resource(zend_resource *res, const
> char *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2(zend_resource *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
> ZEND_API void *zend_fetch_resource_ex(zval *res, const char
> *resource_type_name, int resource_type);
> ZEND_API void *zend_fetch_resource2_ex(zval *res, const char
> *resource_type_name, int *found_type, int resource_type, int
> resource_type2);
>
>    a underworking patch could be found at:
> https://github.com/php/php-src/pull/1042
>
>    any ideas & objections?
>
> thanks
merged, all tests passes.

thanks
>
> --
> Xinchen Hui
> @Laruence
> http://www.laruence.com/



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81758 — Xinchen Hui — 2015-02-04T04:05:18+00:00

URL: https://externals.io/message/81546#81758 · In reply to: #81601

Hey:

On Tue, Feb 3, 2015 at 12:37 AM, François Laupretre
<francois@tekwire.net> wrote:
> > […]
>
> I don't understand how you can delete the resource if you remove the handle from the zend_resource struct. Or would you store the index elsewhere ?

if you use HashTable ,  yes, it's hard to get rid of it, but we can
hidden it from user land..

and actually,  we only use integer index of regular_list for zend_resource..

if we decide to remove handle, then it maybe easy to re-implement it
as a plain c array like zend_resource[];

and when doing realloce, we allocate new segment, and link them togther. etc

thanks
>
> Regards
>
> François
>



-- 
Xinchen Hui
@Laruence
http://www.laruence.com/

---

## #81765 — Stanislav Malyshev — 2015-02-04T06:02:03+00:00

URL: https://externals.io/message/81546#81765 · In reply to: #81546

Hi!

>     as you can see, we use "r" to receive a IS_RESOURCE type, that
> means, check the type in ZEND_FETCH_RESOURCE is overhead..

Except that some functions could receive "z" and decide if it's the
resource or not afterwards... But I guess you could rely on the code
that decides it to check. Some code would crash (or produce some very
bad memory corruption) if somebody would forget to add this check when
porting such extension. Is saving one branch worth it?

>    ZEND_API void *zend_fetch_resource(zval *passed_id, int default_id,
> const char *resource_type_name, int *found_resource_type, int
> num_resource_types, ...)
> 
>    we use va_args to passing resource type, that means, the rescue
> type arguments can not be passed by register but by stack.. which is a
> little low effiicient .

Is it that bad? Functions are passing arguments via the stack all
around. The interface with fetch(), fetch2(), fetch3(), fetch4(), etc.
looks a little clunky.

As for storing the value directly instead of having the list - it would
work for all cases except for two important ones:

1. Persistent resources - they need to be stored somewhere, and not in
zvals that are supposed to be dead at the end of the request.
2. Cleanup at the end for non-persistent ones - zvals may be lost and
not destructed in many exceptional situations. Not destructing the
resource may mean having a stale lock forever or consuming connections
or handles, etc. So there should be some mechanism allowing for
destroying all resources that are transient.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #81766 — francois@tekwire.net — 2015-02-04T06:25:12+00:00

URL: https://externals.io/message/81546#81766 · In reply to: #81758

> De : Xinchen Hui [mailto:laruence@php.net]
> > […]
> handle from the zend_resource struct. Or would you store the index
> elsewhere ?
> 
> if you use HashTable ,  yes, it's hard to get rid of it, but we can
> hidden it from user land..
> 
> and actually,  we only use integer index of regular_list for zend_resource..
> 
> if we decide to remove handle, then it maybe easy to re-implement it
> as a plain c array like zend_resource[];
> 
> and when doing realloce, we allocate new segment, and link them togther.

Anyway, IMO, moving resources from HashTable to a plain C array is a good thing. Allocating segments of 20 structs, for instance, would be fine as a single segment would fit 99.9 % of the cases. This way, you could even compute a pseudo resource handle from the zend_resource address (for `var_dump()`). The only additional thing you would need is a field to mark the resource as deleted/invalid. But setting ptr to `NULL` and type to -1 would be probably enough.

I am interested in the subject of resources because I just implemented a resource abstraction layer in php-ext-gen (https://github.com/flaupretre/php-ext-gen). The objective being to use the same user code for PHP 5 and 7. Maybe you can have a look at the project and give me your opinion.

Regards

François
