diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi index 3644b7cdae5f6120e38c9239254f7e0fb73a8052..e927605384521854d5fd87022b05f1badaae3355 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi @@ -117,8 +117,8 @@ cdef class Metadata: cdef grpc_metadata_array c_metadata_array cdef bint owns_metadata_slices cdef object metadata - cdef void _claim_slice_ownership(self) nogil - cdef void _drop_slice_ownership(self) nogil + cdef void _claim_slice_ownership(self) + cdef void _drop_slice_ownership(self) cdef class Operation: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 30e7b9657a96ffb47db5e15e3e67019cc0d8c579..d7a771333255bbb76ee20d6c3805284d113bc02f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -466,6 +466,10 @@ cdef class _MetadataIterator: else: raise StopIteration +cdef grpc_slice _copy_slice(grpc_slice slice) nogil: + cdef void *start = grpc_slice_start_ptr(slice) + cdef size_t length = grpc_slice_length(slice) + return grpc_slice_from_copied_buffer(<const char *>start, length) cdef class Metadata: @@ -489,8 +493,8 @@ cdef class Metadata: (<Metadatum>self.metadata[i]).c_metadata) def __dealloc__(self): + self._drop_slice_ownership() with nogil: - self._drop_slice_ownership() # this frees the allocated memory for the grpc_metadata_array (although # it'd be nice if that were documented somewhere...) # TODO(atash): document this in the C core @@ -510,15 +514,17 @@ cdef class Metadata: def __iter__(self): return _MetadataIterator(self) - cdef void _claim_slice_ownership(self) nogil: + cdef void _claim_slice_ownership(self): if self.owns_metadata_slices: return for i in range(self.c_metadata_array.count): - grpc_slice_ref(self.c_metadata_array.metadata[i].key) - grpc_slice_ref(self.c_metadata_array.metadata[i].value) + self.c_metadata_array.metadata[i].key = _copy_slice( + self.c_metadata_array.metadata[i].key) + self.c_metadata_array.metadata[i].value = _copy_slice( + self.c_metadata_array.metadata[i].value) self.owns_metadata_slices = True - cdef void _drop_slice_ownership(self) nogil: + cdef void _drop_slice_ownership(self): if not self.owns_metadata_slices: return for i in range(self.c_metadata_array.count):