|
42 | 42 | #define R_SUB_CALLBACK_FT_TYPE 2 |
43 | 43 | #define R_SUB_CLOSURE_TYPE 3 |
44 | 44 |
|
45 | | -int le_redis_sock; |
46 | | - |
47 | 45 | #ifdef PHP_SESSION |
48 | 46 | extern ps_module ps_mod_redis; |
49 | 47 | extern ps_module ps_mod_redis_cluster; |
@@ -426,36 +424,90 @@ static int send_discard_static(RedisSock *redis_sock TSRMLS_DC) { |
426 | 424 | return result; |
427 | 425 | } |
428 | 426 |
|
429 | | -/** |
430 | | - * redis_destructor_redis_sock |
431 | | - */ |
432 | | -static void redis_destructor_redis_sock(zend_resource * rsrc TSRMLS_DC) |
| 427 | +#if (PHP_MAJOR_VERSION < 7) |
| 428 | +void |
| 429 | +free_redis_object(void *object TSRMLS_DC) |
| 430 | +{ |
| 431 | + redis_object *redis = (redis_object *)object; |
| 432 | + |
| 433 | + zend_object_std_dtor(&redis->std TSRMLS_CC); |
| 434 | + if (redis->sock) { |
| 435 | + redis_sock_disconnect(redis->sock TSRMLS_CC); |
| 436 | + redis_free_socket(redis->sock); |
| 437 | + } |
| 438 | + efree(redis); |
| 439 | +} |
| 440 | + |
| 441 | +zend_object_value |
| 442 | +create_redis_object(zend_class_entry *ce TSRMLS_DC) |
| 443 | +{ |
| 444 | + zend_object_value retval; |
| 445 | + redis_object *redis = ecalloc(1, sizeof(redis_object)); |
| 446 | + |
| 447 | + memset(redis, 0, sizeof(redis_object)); |
| 448 | + zend_object_std_init(&redis->std, ce TSRMLS_CC); |
| 449 | + |
| 450 | +#if PHP_VERSION_ID < 50399 |
| 451 | + zval *tmp; |
| 452 | + zend_hash_copy(redis->std.properties, &ce->default_properties, |
| 453 | + (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); |
| 454 | +#endif |
| 455 | + |
| 456 | + retval.handle = zend_objects_store_put(redis, |
| 457 | + (zend_objects_store_dtor_t)zend_objects_destroy_object, |
| 458 | + (zend_objects_free_object_storage_t)free_redis_object, |
| 459 | + NULL TSRMLS_CC); |
| 460 | + retval.handlers = zend_get_std_object_handlers(); |
| 461 | + |
| 462 | + return retval; |
| 463 | +} |
| 464 | +#else |
| 465 | +zend_object_handlers redis_object_handlers; |
| 466 | + |
| 467 | +void |
| 468 | +free_redis_object(zend_object *object) |
| 469 | +{ |
| 470 | + redis_object *redis = (redis_object *)((char *)(object) - XtOffsetOf(redis_object, std)); |
| 471 | + |
| 472 | + zend_object_std_dtor(&redis->std TSRMLS_CC); |
| 473 | + if (redis->sock) { |
| 474 | + redis_sock_disconnect(redis->sock TSRMLS_CC); |
| 475 | + redis_free_socket(redis->sock); |
| 476 | + } |
| 477 | +} |
| 478 | + |
| 479 | +zend_object * |
| 480 | +create_redis_object(zend_class_entry *ce TSRMLS_DC) |
433 | 481 | { |
434 | | - RedisSock *redis_sock = (RedisSock *) rsrc->ptr; |
435 | | - redis_sock_disconnect(redis_sock TSRMLS_CC); |
436 | | - redis_free_socket(redis_sock); |
| 482 | + redis_object *redis = ecalloc(1, sizeof(redis_object) + zend_object_properties_size(ce)); |
| 483 | + |
| 484 | + redis->sock = NULL; |
| 485 | + |
| 486 | + zend_object_std_init(&redis->std, ce TSRMLS_CC); |
| 487 | + object_properties_init(&redis->std, ce); |
| 488 | + |
| 489 | + memcpy(&redis_object_handlers, zend_get_std_object_handlers(), sizeof(redis_object_handlers)); |
| 490 | + redis_object_handlers.offset = XtOffsetOf(redis_object, std); |
| 491 | + redis_object_handlers.free_obj = free_redis_object; |
| 492 | + redis->std.handlers = &redis_object_handlers; |
| 493 | + |
| 494 | + return &redis->std; |
437 | 495 | } |
| 496 | +#endif |
438 | 497 |
|
439 | 498 | static zend_always_inline int |
440 | 499 | redis_sock_get_instance(zval *id, RedisSock **redis_sock TSRMLS_DC, int no_throw) |
441 | 500 | { |
442 | | - zval *socket; |
443 | | - int resource_type = 0; |
| 501 | + redis_object *redis; |
444 | 502 |
|
445 | | - if (Z_TYPE_P(id) == IS_OBJECT && |
446 | | - (socket = zend_hash_str_find(Z_OBJPROP_P(id), "socket", sizeof("socket") - 1)) != NULL |
447 | | - ) { |
| 503 | + if (Z_TYPE_P(id) == IS_OBJECT) { |
448 | 504 | #if (PHP_MAJOR_VERSION < 7) |
449 | | - *redis_sock = (RedisSock *)zend_list_find(Z_LVAL_P(socket), &resource_type); |
| 505 | + redis = (redis_object *)zend_objects_get_address(id TSRMLS_CC); |
450 | 506 | #else |
451 | | - *redis_sock = NULL; |
452 | | - |
453 | | - if (Z_RES_P(socket) != NULL) { |
454 | | - *redis_sock = (RedisSock *)Z_RES_P(socket)->ptr; |
455 | | - resource_type = Z_RES_P(socket)->type; |
456 | | - } |
| 507 | + redis = (redis_object *)((char *)Z_OBJ_P(id) - XtOffsetOf(redis_object, std)); |
457 | 508 | #endif |
458 | | - if (*redis_sock && resource_type == le_redis_sock) { |
| 509 | + if (redis->sock) { |
| 510 | + *redis_sock = redis->sock; |
459 | 511 | return 0; |
460 | 512 | } |
461 | 513 | } |
@@ -580,6 +632,7 @@ PHP_MINIT_FUNCTION(redis) |
580 | 632 | /* Redis class */ |
581 | 633 | INIT_CLASS_ENTRY(redis_class_entry, "Redis", redis_functions); |
582 | 634 | redis_ce = zend_register_internal_class(&redis_class_entry TSRMLS_CC); |
| 635 | + redis_ce->create_object = create_redis_object; |
583 | 636 |
|
584 | 637 | /* RedisArray class */ |
585 | 638 | INIT_CLASS_ENTRY(redis_array_class_entry, "RedisArray", redis_array_functions); |
@@ -616,12 +669,6 @@ PHP_MINIT_FUNCTION(redis) |
616 | 669 | #endif |
617 | 670 | ); |
618 | 671 |
|
619 | | - le_redis_sock = zend_register_list_destructors_ex( |
620 | | - redis_destructor_redis_sock, |
621 | | - NULL, |
622 | | - redis_sock_name, module_number |
623 | | - ); |
624 | | - |
625 | 672 | /* Add shared class constants to Redis and RedisCluster objects */ |
626 | 673 | add_class_constants(redis_ce, 0 TSRMLS_CC); |
627 | 674 | add_class_constants(redis_cluster_ce, 1 TSRMLS_CC); |
@@ -737,13 +784,15 @@ PHP_METHOD(Redis, pconnect) |
737 | 784 | } |
738 | 785 | /* }}} */ |
739 | 786 |
|
740 | | -PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) { |
741 | | - zval *object, *socket; |
| 787 | +PHP_REDIS_API int |
| 788 | +redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) |
| 789 | +{ |
| 790 | + zval *object; |
742 | 791 | char *host = NULL, *persistent_id = NULL; |
743 | 792 | zend_long port = -1, retry_interval = 0; |
744 | 793 | strlen_t host_len, persistent_id_len; |
745 | 794 | double timeout = 0.0; |
746 | | - RedisSock *redis_sock = NULL; |
| 795 | + redis_object *redis; |
747 | 796 |
|
748 | 797 | #ifdef ZTS |
749 | 798 | /* not sure how in threaded mode this works so disabled persistence at |
@@ -779,40 +828,24 @@ PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) { |
779 | 828 | port = 6379; |
780 | 829 | } |
781 | 830 |
|
782 | | - /* if there is a redis sock already we have to remove it from the list */ |
783 | | - if (redis_sock_get(object, &redis_sock TSRMLS_CC, 1) >= 0) { |
784 | | - if ((socket = zend_hash_str_find(Z_OBJPROP_P(object), "socket", sizeof("socket") - 1)) == NULL) |
785 | | - { |
786 | | - /* maybe there is a socket but the id isn't known.. what to do? */ |
787 | | - } else { |
788 | | - /* The refcount should be decreased and destructor invoked */ |
789 | 831 | #if (PHP_MAJOR_VERSION < 7) |
790 | | - zend_list_delete(Z_LVAL_P(socket)); |
| 832 | + redis = (redis_object *)zend_objects_get_address(object TSRMLS_CC); |
791 | 833 | #else |
792 | | - zend_list_close(Z_RES_P(socket)); |
| 834 | + redis = (redis_object *)((char *)Z_OBJ_P(object) - XtOffsetOf(redis_object, std)); |
793 | 835 | #endif |
794 | | - } |
| 836 | + /* if there is a redis sock already we have to remove it */ |
| 837 | + if (redis->sock) { |
| 838 | + redis_sock_disconnect(redis->sock TSRMLS_CC); |
| 839 | + redis_free_socket(redis->sock); |
795 | 840 | } |
796 | 841 |
|
797 | | - redis_sock = redis_sock_create(host, host_len, port, timeout, persistent, |
| 842 | + redis->sock = redis_sock_create(host, host_len, port, timeout, persistent, |
798 | 843 | persistent_id, retry_interval, 0); |
799 | 844 |
|
800 | | - if (redis_sock_server_open(redis_sock, 1 TSRMLS_CC) < 0) { |
801 | | - redis_free_socket(redis_sock); |
| 845 | + if (redis_sock_server_open(redis->sock, 1 TSRMLS_CC) < 0) { |
| 846 | + redis_free_socket(redis->sock); |
802 | 847 | return FAILURE; |
803 | 848 | } |
804 | | -#if (PHP_MAJOR_VERSION < 7) |
805 | | - int id; |
806 | | -#if PHP_VERSION_ID >= 50400 |
807 | | - id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC); |
808 | | -#else |
809 | | - id = zend_list_insert(redis_sock, le_redis_sock); |
810 | | -#endif |
811 | | - add_property_resource(object, "socket", id); |
812 | | -#else |
813 | | - zval *id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC); |
814 | | - add_property_resource(object, "socket", Z_RES_P(id)); |
815 | | -#endif |
816 | 849 |
|
817 | 850 | return SUCCESS; |
818 | 851 | } |
|
0 commit comments