Skip to content

Commit fe1790c

Browse files
authored
Fix Multiple Request for PHP (#7008)
* Add scripts to test multirequest * chmod ug+x multirequest.sh * Add continuous test * Compile c extension * Class entry is obsolete in the second request 1) Needes to use class name in persistent map 2) Invalidate class entry stored in descriptor * Add new files to dist * Fix compile_extension * Cleanup outputs for phpize
1 parent 39492b6 commit fe1790c

File tree

8 files changed

+133
-21
lines changed

8 files changed

+133
-21
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ php/tests/old_protoc
141141
php/tests/protobuf/
142142
php/tests/core
143143
php/tests/vgcore*
144+
php/tests/multirequest.result
145+
php/tests/nohup.out
144146
php/ext/google/protobuf/.libs/
145147
php/ext/google/protobuf/Makefile.fragments
146148
php/ext/google/protobuf/Makefile.global

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,8 @@ php_EXTRA_DIST= \
877877
php/tests/generated_service_test.php \
878878
php/tests/map_field_test.php \
879879
php/tests/memory_leak_test.php \
880+
php/tests/multirequest.php \
881+
php/tests/multirequest.sh \
880882
php/tests/php_implementation_test.php \
881883
php/tests/proto/empty/echo.proto \
882884
php/tests/proto/test.proto \

php/ext/google/protobuf/protobuf.c

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ static upb_inttable upb_def_to_enumdesc_map_persistent;
4949
// Global map from message/enum's php class entry to corresponding wrapper
5050
// Descriptor/EnumDescriptor instances.
5151
static HashTable* ce_to_php_obj_map;
52-
static upb_inttable ce_to_desc_map_persistent;
53-
static upb_inttable ce_to_enumdesc_map_persistent;
52+
static upb_strtable ce_to_desc_map_persistent;
53+
static upb_strtable ce_to_enumdesc_map_persistent;
5454
// Global map from message/enum's proto fully-qualified name to corresponding
5555
// wrapper Descriptor/EnumDescriptor instances.
5656
static upb_strtable proto_to_desc_map_persistent;
@@ -138,33 +138,55 @@ PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce) {
138138
}
139139

140140
void add_ce_desc(const zend_class_entry* ce, DescriptorInternal* desc) {
141-
upb_inttable_insertptr(&ce_to_desc_map_persistent,
142-
ce, upb_value_ptr(desc));
141+
#if PHP_MAJOR_VERSION < 7
142+
const char* klass = ce->name;
143+
#else
144+
const char* klass = ZSTR_VAL(ce->name);
145+
#endif
146+
upb_strtable_insert(&ce_to_desc_map_persistent, klass,
147+
upb_value_ptr(desc));
143148
}
144149

145150
DescriptorInternal* get_ce_desc(const zend_class_entry* ce) {
151+
#if PHP_MAJOR_VERSION < 7
152+
const char* klass = ce->name;
153+
#else
154+
const char* klass = ZSTR_VAL(ce->name);
155+
#endif
156+
146157
upb_value v;
147158
#ifndef NDEBUG
148159
v.ctype = UPB_CTYPE_PTR;
149160
#endif
150-
if (!upb_inttable_lookupptr(&ce_to_desc_map_persistent, ce, &v)) {
161+
162+
if (!upb_strtable_lookup(&ce_to_desc_map_persistent, klass, &v)) {
151163
return NULL;
152164
} else {
153165
return upb_value_getptr(v);
154166
}
155167
}
156168

157169
void add_ce_enumdesc(const zend_class_entry* ce, EnumDescriptorInternal* desc) {
158-
upb_inttable_insertptr(&ce_to_enumdesc_map_persistent,
159-
ce, upb_value_ptr(desc));
170+
#if PHP_MAJOR_VERSION < 7
171+
const char* klass = ce->name;
172+
#else
173+
const char* klass = ZSTR_VAL(ce->name);
174+
#endif
175+
upb_strtable_insert(&ce_to_enumdesc_map_persistent, klass,
176+
upb_value_ptr(desc));
160177
}
161178

162179
EnumDescriptorInternal* get_ce_enumdesc(const zend_class_entry* ce) {
180+
#if PHP_MAJOR_VERSION < 7
181+
const char* klass = ce->name;
182+
#else
183+
const char* klass = ZSTR_VAL(ce->name);
184+
#endif
163185
upb_value v;
164186
#ifndef NDEBUG
165187
v.ctype = UPB_CTYPE_PTR;
166188
#endif
167-
if (!upb_inttable_lookupptr(&ce_to_enumdesc_map_persistent, ce, &v)) {
189+
if (!upb_strtable_lookup(&ce_to_enumdesc_map_persistent, klass, &v)) {
168190
return NULL;
169191
} else {
170192
return upb_value_getptr(v);
@@ -330,8 +352,8 @@ static void php_proto_hashtable_descriptor_release(zval* value) {
330352
static void initialize_persistent_descriptor_pool(TSRMLS_D) {
331353
upb_inttable_init(&upb_def_to_desc_map_persistent, UPB_CTYPE_PTR);
332354
upb_inttable_init(&upb_def_to_enumdesc_map_persistent, UPB_CTYPE_PTR);
333-
upb_inttable_init(&ce_to_desc_map_persistent, UPB_CTYPE_PTR);
334-
upb_inttable_init(&ce_to_enumdesc_map_persistent, UPB_CTYPE_PTR);
355+
upb_strtable_init(&ce_to_desc_map_persistent, UPB_CTYPE_PTR);
356+
upb_strtable_init(&ce_to_enumdesc_map_persistent, UPB_CTYPE_PTR);
335357
upb_strtable_init(&proto_to_desc_map_persistent, UPB_CTYPE_PTR);
336358
upb_strtable_init(&class_to_desc_map_persistent, UPB_CTYPE_PTR);
337359

@@ -360,7 +382,29 @@ static PHP_RINIT_FUNCTION(protobuf) {
360382
generated_pool_php = NULL;
361383
internal_generated_pool_php = NULL;
362384

363-
if (!PROTOBUF_G(keep_descriptor_pool_after_request)) {
385+
if (PROTOBUF_G(keep_descriptor_pool_after_request)) {
386+
// Needs to clean up obsolete class entry
387+
upb_strtable_iter i;
388+
upb_value v;
389+
390+
DescriptorInternal* desc;
391+
for(upb_strtable_begin(&i, &ce_to_desc_map_persistent);
392+
!upb_strtable_done(&i);
393+
upb_strtable_next(&i)) {
394+
v = upb_strtable_iter_value(&i);
395+
desc = upb_value_getptr(v);
396+
desc->klass = NULL;
397+
}
398+
399+
EnumDescriptorInternal* enumdesc;
400+
for(upb_strtable_begin(&i, &ce_to_enumdesc_map_persistent);
401+
!upb_strtable_done(&i);
402+
upb_strtable_next(&i)) {
403+
v = upb_strtable_iter_value(&i);
404+
enumdesc = upb_value_getptr(v);
405+
enumdesc->klass = NULL;
406+
}
407+
} else {
364408
initialize_persistent_descriptor_pool(TSRMLS_C);
365409
}
366410

@@ -410,8 +454,8 @@ static void cleanup_persistent_descriptor_pool(TSRMLS_D) {
410454

411455
upb_inttable_uninit(&upb_def_to_desc_map_persistent);
412456
upb_inttable_uninit(&upb_def_to_enumdesc_map_persistent);
413-
upb_inttable_uninit(&ce_to_desc_map_persistent);
414-
upb_inttable_uninit(&ce_to_enumdesc_map_persistent);
457+
upb_strtable_uninit(&ce_to_desc_map_persistent);
458+
upb_strtable_uninit(&ce_to_enumdesc_map_persistent);
415459
upb_strtable_uninit(&proto_to_desc_map_persistent);
416460
upb_strtable_uninit(&class_to_desc_map_persistent);
417461
}

php/tests/compile_extension.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
#!/bin/bash
22

3-
EXTENSION_PATH=$1
3+
VERSION=$2
44

5-
pushd $EXTENSION_PATH
5+
export PATH=/usr/local/php-$VERSION/bin:$PATH
6+
export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH
7+
export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH
8+
9+
pushd ../ext/google/protobuf
610
make clean || true
711
set -e
812
# Add following in configure for debug: --enable-debug CFLAGS='-g -O0'

php/tests/multirequest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
if (extension_loaded("protobuf")) {
4+
require_once('memory_leak_test.php');
5+
echo "<p>protobuf loaded</p>";
6+
} else {
7+
echo "<p>protobuf not loaded</p>";
8+
}

php/tests/multirequest.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Compile c extension
5+
VERSION=7.4
6+
PORT=12345
7+
8+
export PATH=/usr/local/php-$VERSION/bin:$PATH
9+
export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH
10+
export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH
11+
/bin/bash ./compile_extension.sh $VERSION
12+
13+
nohup php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so -S localhost:$PORT multirequest.php 2>&1 &
14+
15+
sleep 1
16+
17+
wget http://localhost:$PORT/multirequest.result -O multirequest.result
18+
wget http://localhost:$PORT/multirequest.result -O multirequest.result
19+
20+
pushd ../ext/google/protobuf
21+
phpize --clean
22+
popd
23+
24+
PID=`ps | grep "php" | awk '{print $1}'`
25+
echo $PID
26+
27+
if [[ -z "$PID" ]]
28+
then
29+
echo "Failed"
30+
exit 1
31+
else
32+
kill $PID
33+
echo "Succeeded"
34+
fi

php/tests/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$V
77
export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH
88

99
# Compile c extension
10-
/bin/bash ./compile_extension.sh ../ext/google/protobuf
10+
/bin/bash ./compile_extension.sh $VERSION
1111

1212
tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php descriptors_test.php wrapper_type_setters_test.php)
1313

tests.sh

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,9 @@ build_php5.5_mixed() {
534534
pushd php
535535
rm -rf vendor
536536
composer update
537-
/bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
537+
pushd tests
538+
/bin/bash ./compile_extension.sh 5.5
539+
popd
538540
php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
539541
popd
540542
}
@@ -584,7 +586,9 @@ build_php5.6_mixed() {
584586
pushd php
585587
rm -rf vendor
586588
composer update
587-
/bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
589+
pushd tests
590+
/bin/bash ./compile_extension.sh 5.6
591+
popd
588592
php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
589593
popd
590594
}
@@ -658,7 +662,9 @@ build_php7.0_mixed() {
658662
pushd php
659663
rm -rf vendor
660664
composer update
661-
/bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
665+
pushd tests
666+
/bin/bash ./compile_extension.sh 7.0
667+
popd
662668
php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
663669
popd
664670
}
@@ -706,6 +712,13 @@ build_php_compatibility() {
706712
php/tests/compatibility_test.sh $LAST_RELEASED
707713
}
708714

715+
build_php_multirequest() {
716+
use_php 7.4
717+
pushd php/tests
718+
./multirequest.sh
719+
popd
720+
}
721+
709722
build_php7.1() {
710723
use_php 7.1
711724
pushd php
@@ -737,7 +750,9 @@ build_php7.1_mixed() {
737750
pushd php
738751
rm -rf vendor
739752
composer update
740-
/bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
753+
pushd tests
754+
/bin/bash ./compile_extension.sh 7.1
755+
popd
741756
php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
742757
popd
743758
}
@@ -790,7 +805,9 @@ build_php7.4_mixed() {
790805
pushd php
791806
rm -rf vendor
792807
composer update
793-
/bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
808+
pushd tests
809+
/bin/bash ./compile_extension.sh 7.4
810+
popd
794811
php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
795812
popd
796813
pushd php/ext/google/protobuf
@@ -840,6 +857,7 @@ build_php_all_32() {
840857

841858
build_php_all() {
842859
build_php_all_32 true
860+
build_php_multirequest
843861
build_php_compatibility
844862
}
845863

0 commit comments

Comments
 (0)