|
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