diff --git a/hphp/runtime/ext/thrift/binary.cpp b/hphp/runtime/ext/thrift/binary.cpp index d525c1dbf..1b3ff8e86 100644 --- a/hphp/runtime/ext/thrift/binary.cpp +++ b/hphp/runtime/ext/thrift/binary.cpp @@ -471,6 +471,8 @@ void f_thrift_protocol_write_binary(CObjRef transportobj, CStrRef method_name, Variant spec = f_hphp_get_static_property(request_struct->o_getClassName(), "_TSPEC"); binary_serialize_spec(request_struct, transport, spec.toArray()); + + transport.flush(); } Variant f_thrift_protocol_read_binary(CObjRef transportobj, diff --git a/hphp/runtime/ext/thrift/compact.cpp b/hphp/runtime/ext/thrift/compact.cpp index 650666ebe..550ea0440 100644 --- a/hphp/runtime/ext/thrift/compact.cpp +++ b/hphp/runtime/ext/thrift/compact.cpp @@ -164,8 +164,8 @@ static void thrift_error(CStrRef what, TError why) { class CompactWriter { public: - explicit CompactWriter(CObjRef _transportobj) : - transport(_transportobj), + explicit CompactWriter(PHPOutputTransport *transport) : + transport(transport), version(VERSION), state(STATE_CLEAR), lastFieldNum(0), @@ -192,7 +192,8 @@ class CompactWriter { } private: - PHPOutputTransport transport; + PHPOutputTransport* transport; + uint8_t version; CState state; uint16_t lastFieldNum; @@ -328,7 +329,7 @@ class CompactWriter { bits = htolell(u.i); } - transport.write((char*)&bits, 8); + transport->write((char*)&bits, 8); } break; @@ -338,7 +339,7 @@ class CompactWriter { String s = value.toString(); auto slice = s.slice(); writeVarint(slice.len); - transport.write(slice.ptr, slice.len); + transport->write(slice.ptr, slice.len); break; } @@ -433,7 +434,7 @@ class CompactWriter { } void writeUByte(uint8_t n) { - transport.writeI8(n); + transport->writeI8(n); } void writeI(int64_t n) { @@ -454,13 +455,13 @@ class CompactWriter { } } - transport.write((char*)buf, wsize); + transport->write((char*)buf, wsize); } void writeString(CStrRef s) { auto slice = s.slice(); writeVarint(slice.len); - transport.write(slice.ptr, slice.len); + transport->write(slice.ptr, slice.len); } uint64_t i64ToZigzag(int64_t n) { @@ -920,10 +921,14 @@ void f_thrift_protocol_write_compact(CObjRef transportobj, int64_t msgtype, CObjRef request_struct, int seqid) { - CompactWriter writer(transportobj); + PHPOutputTransport transport(transportobj); + + CompactWriter writer(&transport); writer.setWriteVersion(s_compact_request_data->version); writer.writeHeader(method_name, (uint8_t)msgtype, (uint32_t)seqid); writer.write(request_struct); + + transport.flush(); } Variant f_thrift_protocol_read_compact(CObjRef transportobj, diff --git a/hphp/runtime/ext/thrift/transport.h b/hphp/runtime/ext/thrift/transport.h index b5b74b8e5..28d1724b0 100644 --- a/hphp/runtime/ext/thrift/transport.h +++ b/hphp/runtime/ext/thrift/transport.h @@ -139,14 +139,15 @@ public: } ~PHPOutputTransport() { - // flush() and directFlush() call into user code which may throw - // an exception. Because this is a destructor, we might already be + // Because this is a destructor, we might already be // in the process of unwinding when this function is called, so we // need to ensure that no exceptions can escape so that the unwinder // does not terminate the process. try { - flush(); - directFlush(); + if (buffer_used != 0) { + raise_warning("runtime/ext_thrift: " + "Output buffer has %lu unflushed bytes", buffer_used); + } } catch (...) { handle_destructor_exception(); } @@ -154,7 +155,7 @@ public: void write(const char* data, size_t len) { if ((len + buffer_used) > buffer_size) { - flush(); + writeBufferToTransport(); } if (len > buffer_size) { directWrite(data, len); @@ -194,7 +195,7 @@ public: write(str, len); } - void flush() { + void writeBufferToTransport() { if (buffer_used) { directWrite(buffer, buffer_used); buffer_ptr = buffer; @@ -202,6 +203,11 @@ public: } } + void flush() { + writeBufferToTransport(); + directFlush(); + } + protected: void directFlush() { t->o_invoke_few_args(s_flush, 0);