1 module grpc.common.metadata; 2 import interop.headers; 3 import grpc.logger; 4 import grpc.common.cq; 5 import grpc.core.utils; 6 import grpc.core.sync.mutex; 7 import grpc.core.resource; 8 import interop.functors; 9 import automem; 10 import core.lifetime; 11 12 /* 13 INFO: This ARRAY SHOULD *NEVER* be shared across threads. 14 It is not thread-safe. 15 */ 16 struct MetadataArray { 17 @safe @nogc: 18 private { 19 shared(Mutex) mutex; 20 SharedResource _meta; 21 } 22 23 inout(grpc_metadata_array)* handle() inout @trusted nothrow { 24 return cast(typeof(return)) _meta.handle; 25 } 26 27 @property ulong capacity() { 28 mutex.lock; 29 scope(exit) mutex.unlock; 30 31 return handle.capacity; 32 } 33 34 @property ulong count() { 35 mutex.lock; 36 scope(exit) mutex.unlock; 37 38 grpc_metadata_array* arr = handle; 39 40 ulong count = arr.count; 41 return count; 42 } 43 44 grpc_metadata* opIndex(size_t i1) { 45 mutex.lock; 46 scope(exit) mutex.unlock; 47 assert(i1 < count, "out of range"); 48 return () @trusted { 49 return &handle.metadata[i1]; 50 } (); 51 } 52 53 void cleanup() { 54 if (handle.metadata == null) return; 55 56 () @trusted { 57 grpcwrap_metadata_array_destroy_metadata_only(handle); 58 } (); 59 60 handle.metadata = null; 61 handle.count = 0; 62 handle.capacity = 0; 63 } 64 65 static MetadataArray create() @trusted { 66 static bool release(shared(void)* ptr) @trusted nothrow { 67 grpc_metadata_array* array = cast(grpc_metadata_array*)ptr; 68 if (array.metadata) { 69 for (int i = 0; i < array.count; i++) { 70 grpc_slice_unref(array.metadata[i].key); 71 grpc_slice_unref(array.metadata[i].value); 72 } 73 gpr_free(cast(void*)array.metadata); 74 array.metadata = null; 75 } 76 gpr_free(cast(void*)ptr); 77 return true; 78 } 79 80 grpc_metadata_array* mt = cast(grpc_metadata_array*)gpr_zalloc((grpc_metadata_array).sizeof); 81 if(mt != null) { 82 grpcwrap_metadata_array_init(mt, 1); 83 return MetadataArray(cast(shared)Mutex.create(), SharedResource(cast(shared)mt, &release)); 84 } 85 assert(0, "malloc error"); 86 } 87 88 ~this() { 89 _meta.forceRelease(); 90 } 91 } 92