Do not suppress exceptions thrown by PHP transport
Currerntly, if TServiceRouterTransport::flush throws an exception, this exception is swallowed non-chalantly by Thrift's extension layer. This should not happen.
Esse commit está contido em:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário