From 4abd86c7fa5b8094be64af835593931e21ee562e Mon Sep 17 00:00:00 2001 From: Hannah Shi Date: Fri, 8 Nov 2019 17:44:06 +0000 Subject: [PATCH] reduce 3 times memcpy of message to 1 time only. --- src/php/ext/grpc/byte_buffer.c | 30 ++++++++++++++++++++++++++++++ src/php/ext/grpc/byte_buffer.h | 4 ++++ src/php/ext/grpc/call.c | 23 +++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/php/ext/grpc/byte_buffer.c b/src/php/ext/grpc/byte_buffer.c index 9c9a6fc3a02..2c090f2646e 100644 --- a/src/php/ext/grpc/byte_buffer.c +++ b/src/php/ext/grpc/byte_buffer.c @@ -31,6 +31,8 @@ grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { return buffer; } +#if PHP_MAJOR_VERSION < 7 + void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, size_t *out_length) { grpc_byte_buffer_reader reader; @@ -50,3 +52,31 @@ void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, *out_string = string; *out_length = length; } + +#else + +zend_string* byte_buffer_to_zend_string(grpc_byte_buffer *buffer) { + grpc_byte_buffer_reader reader; + if (buffer == NULL || !grpc_byte_buffer_reader_init(&reader, buffer)) { + /* TODO(dgq): distinguish between the error cases. */ + return NULL; + } + + const size_t length = grpc_byte_buffer_length(reader.buffer_out); + zend_string* zstr = zend_string_alloc(length, 0); + + char* buf = ZSTR_VAL(zstr); + grpc_slice next; + while (grpc_byte_buffer_reader_next(&reader, &next) != 0) { + const size_t next_len = GRPC_SLICE_LENGTH(next); + memcpy(buf, GRPC_SLICE_START_PTR(next), next_len); + buf += next_len; + grpc_slice_unref(next); + } + + *buf = '\0'; + + return zstr; +} + +#endif // PHP_MAJOR_VERSION < 7 diff --git a/src/php/ext/grpc/byte_buffer.h b/src/php/ext/grpc/byte_buffer.h index ca0435ee14a..e58d1310b80 100644 --- a/src/php/ext/grpc/byte_buffer.h +++ b/src/php/ext/grpc/byte_buffer.h @@ -23,7 +23,11 @@ grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length); +#if PHP_MAJOR_VERSION < 7 void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, size_t *out_length); +#else +zend_string* byte_buffer_to_zend_string(grpc_byte_buffer *buffer); +#endif // PHP_MAJOR_VERSION < 7 #endif /* NET_GRPC_PHP_GRPC_BYTE_BUFFER_H_ */ diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 46d1e22f1f8..66b26716b13 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -294,8 +294,13 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer *message; int cancelled; grpc_call_error error; + + #if PHP_MAJOR_VERSION < 7 char *message_str; size_t message_len; + #else + zend_string* zmessage = NULL; + #endif // PHP_MAJOR_VERSION < 7 grpc_metadata_array_init(&metadata); grpc_metadata_array_init(&trailing_metadata); @@ -483,12 +488,28 @@ PHP_METHOD(Call, startBatch) { PHP_GRPC_DELREF(array); break; case GRPC_OP_RECV_MESSAGE: +#if PHP_MAJOR_VERSION < 7 byte_buffer_to_string(message, &message_str, &message_len); +#else + zmessage = byte_buffer_to_zend_string(message); +#endif // PHP_MAJOR_VERSION < 7 + +#if PHP_MAJOR_VERSION < 7 if (message_str == NULL) { +#else + if (zmessage == NULL) { +#endif // PHP_MAJOR_VERSION < 7 add_property_null(result, "message"); } else { +#if PHP_MAJOR_VERSION < 7 php_grpc_add_property_stringl(result, "message", message_str, message_len, false); +#else + zval zmessage_val; + ZVAL_NEW_STR(&zmessage_val, zmessage); + add_property_zval(result, "message", &zmessage_val); + zval_ptr_dtor(&zmessage_val); +#endif // PHP_MAJOR_VERSION < 7 } break; case GRPC_OP_RECV_STATUS_ON_CLIENT: @@ -537,7 +558,9 @@ cleanup: } if (ops[i].op == GRPC_OP_RECV_MESSAGE) { grpc_byte_buffer_destroy(message); + #if PHP_MAJOR_VERSION < 7 PHP_GRPC_FREE_STD_ZVAL(message_str); + #endif // PHP_MAJOR_VERSION < 7 } } RETURN_DESTROY_ZVAL(result);