Skip to content
Snippets Groups Projects
Commit 828e0ad4 authored by Michael Lumish's avatar Michael Lumish
Browse files

Merge pull request #2156 from jcanizales/fix-garbage-flags

Ensure op flags don't have garbage from malloc
parents 40c9481e 88487046
No related branches found
No related tags found
No related merge requests found
...@@ -33,53 +33,51 @@ ...@@ -33,53 +33,51 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#import "GRPCChannel.h"
typedef void(^GRPCCompletionHandler)(NSDictionary *);
@protocol GRPCOp <NSObject>
- (void)getOp:(grpc_op *)op; #import "GRPCChannel.h"
@interface GRPCOperation : NSObject
@property(nonatomic, readonly) grpc_op op;
// Guaranteed to be called when the operation has finished.
- (void)finish; - (void)finish;
@end @end
@interface GRPCOpSendMetadata : NSObject <GRPCOp> @interface GRPCOpSendMetadata : GRPCOperation
- (instancetype)initWithMetadata:(NSDictionary *)metadata - (instancetype)initWithMetadata:(NSDictionary *)metadata
handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
@end @end
@interface GRPCOpSendMessage : NSObject <GRPCOp> @interface GRPCOpSendMessage : GRPCOperation
- (instancetype)initWithMessage:(NSData *)message - (instancetype)initWithMessage:(NSData *)message
handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
@end @end
@interface GRPCOpSendClose : NSObject <GRPCOp> @interface GRPCOpSendClose : GRPCOperation
- (instancetype)initWithHandler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHandler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
@end @end
@interface GRPCOpRecvMetadata : NSObject <GRPCOp> @interface GRPCOpRecvMetadata : GRPCOperation
- (instancetype)initWithHandler:(void(^)(NSDictionary *))handler NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHandler:(void(^)(NSDictionary *))handler NS_DESIGNATED_INITIALIZER;
@end @end
@interface GRPCOpRecvMessage : NSObject <GRPCOp> @interface GRPCOpRecvMessage : GRPCOperation
- (instancetype)initWithHandler:(void(^)(grpc_byte_buffer *))handler NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHandler:(void(^)(grpc_byte_buffer *))handler NS_DESIGNATED_INITIALIZER;
@end @end
@interface GRPCOpRecvStatus : NSObject <GRPCOp> @interface GRPCOpRecvStatus : GRPCOperation
- (instancetype)initWithHandler:(void(^)(NSError *, NSDictionary *))handler NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHandler:(void(^)(NSError *, NSDictionary *))handler
NS_DESIGNATED_INITIALIZER;
@end @end
......
...@@ -41,110 +41,85 @@ ...@@ -41,110 +41,85 @@
#import "NSData+GRPC.h" #import "NSData+GRPC.h"
#import "NSError+GRPC.h" #import "NSError+GRPC.h"
@implementation GRPCOpSendMetadata{ @implementation GRPCOperation {
void(^_handler)(void); @protected
grpc_metadata *_sendMetadata; // Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being
size_t _count; // initialized to zero.
grpc_op _op;
void(^_handler)();
} }
- (void)finish {
if (_handler) {
_handler();
}
}
@end
@implementation GRPCOpSendMetadata
- (instancetype)init { - (instancetype)init {
return [self initWithMetadata:nil handler:nil]; return [self initWithMetadata:nil handler:nil];
} }
- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)(void))handler { - (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)())handler {
if (self = [super init]) { if (self = [super init]) {
_sendMetadata = [metadata grpc_metadataArray]; _op.op = GRPC_OP_SEND_INITIAL_METADATA;
_count = metadata.count; _op.data.send_initial_metadata.count = metadata.count;
_op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray;
_handler = handler; _handler = handler;
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = _count;
op->data.send_initial_metadata.metadata = _sendMetadata;
}
- (void)finish {
if (_handler) {
_handler();
}
}
- (void)dealloc { - (void)dealloc {
gpr_free(_sendMetadata); gpr_free(_op.data.send_initial_metadata.metadata);
} }
@end @end
@implementation GRPCOpSendMessage{ @implementation GRPCOpSendMessage
void(^_handler)(void);
grpc_byte_buffer *_byteBuffer;
}
- (instancetype)init { - (instancetype)init {
return [self initWithMessage:nil handler:nil]; return [self initWithMessage:nil handler:nil];
} }
- (instancetype)initWithMessage:(NSData *)message handler:(void (^)(void))handler { - (instancetype)initWithMessage:(NSData *)message handler:(void (^)())handler {
if (!message) { if (!message) {
[NSException raise:NSInvalidArgumentException format:@"message cannot be nil"]; [NSException raise:NSInvalidArgumentException format:@"message cannot be nil"];
} }
if (self = [super init]) { if (self = [super init]) {
_byteBuffer = [message grpc_byteBuffer]; _op.op = GRPC_OP_SEND_MESSAGE;
_op.data.send_message = message.grpc_byteBuffer;
_handler = handler; _handler = handler;
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = _byteBuffer;
}
- (void)finish {
if (_handler) {
_handler();
}
}
- (void)dealloc { - (void)dealloc {
gpr_free(_byteBuffer); gpr_free(_op.data.send_message);
} }
@end @end
@implementation GRPCOpSendClose{ @implementation GRPCOpSendClose
void(^_handler)(void);
}
- (instancetype)init { - (instancetype)init {
return [self initWithHandler:nil]; return [self initWithHandler:nil];
} }
- (instancetype)initWithHandler:(void (^)(void))handler { - (instancetype)initWithHandler:(void (^)())handler {
if (self = [super init]) { if (self = [super init]) {
_op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
_handler = handler; _handler = handler;
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
}
- (void)finish {
if (_handler) {
_handler();
}
}
@end @end
@implementation GRPCOpRecvMetadata{ @implementation GRPCOpRecvMetadata {
void(^_handler)(NSDictionary *); grpc_metadata_array _headers;
grpc_metadata_array _recvInitialMetadata;
} }
- (instancetype) init { - (instancetype) init {
...@@ -153,33 +128,27 @@ ...@@ -153,33 +128,27 @@
- (instancetype) initWithHandler:(void (^)(NSDictionary *))handler { - (instancetype) initWithHandler:(void (^)(NSDictionary *))handler {
if (self = [super init]) { if (self = [super init]) {
_handler = handler; _op.op = GRPC_OP_RECV_INITIAL_METADATA;
grpc_metadata_array_init(&_recvInitialMetadata); grpc_metadata_array_init(&_headers);
_op.data.recv_initial_metadata = &_headers;
if (handler) {
_handler = ^{
NSDictionary *metadata = [NSDictionary grpc_dictionaryFromMetadataArray:_headers];
handler(metadata);
};
}
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &_recvInitialMetadata;
}
- (void)finish {
NSDictionary *metadata = [NSDictionary grpc_dictionaryFromMetadataArray:_recvInitialMetadata];
if (_handler) {
_handler(metadata);
}
}
- (void)dealloc { - (void)dealloc {
grpc_metadata_array_destroy(&_recvInitialMetadata); grpc_metadata_array_destroy(&_headers);
} }
@end @end
@implementation GRPCOpRecvMessage{ @implementation GRPCOpRecvMessage{
void(^_handler)(grpc_byte_buffer *); grpc_byte_buffer *_receivedMessage;
grpc_byte_buffer *_recvMessage;
} }
- (instancetype)init { - (instancetype)init {
...@@ -188,30 +157,24 @@ ...@@ -188,30 +157,24 @@
- (instancetype)initWithHandler:(void (^)(grpc_byte_buffer *))handler { - (instancetype)initWithHandler:(void (^)(grpc_byte_buffer *))handler {
if (self = [super init]) { if (self = [super init]) {
_handler = handler; _op.op = GRPC_OP_RECV_MESSAGE;
_op.data.recv_message = &_receivedMessage;
if (handler) {
_handler = ^{
handler(_receivedMessage);
};
}
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &_recvMessage;
}
- (void)finish {
if (_handler) {
_handler(_recvMessage);
}
}
@end @end
@implementation GRPCOpRecvStatus{ @implementation GRPCOpRecvStatus{
void(^_handler)(NSError *, NSDictionary *);
grpc_status_code _statusCode; grpc_status_code _statusCode;
char *_details; char *_details;
size_t _detailsCapacity; size_t _detailsCapacity;
grpc_metadata_array _metadata; grpc_metadata_array _trailers;
} }
- (instancetype) init { - (instancetype) init {
...@@ -220,30 +183,25 @@ ...@@ -220,30 +183,25 @@
- (instancetype) initWithHandler:(void (^)(NSError *, NSDictionary *))handler { - (instancetype) initWithHandler:(void (^)(NSError *, NSDictionary *))handler {
if (self = [super init]) { if (self = [super init]) {
_handler = handler; _op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
grpc_metadata_array_init(&_metadata); _op.data.recv_status_on_client.status = &_statusCode;
_op.data.recv_status_on_client.status_details = &_details;
_op.data.recv_status_on_client.status_details_capacity = &_detailsCapacity;
grpc_metadata_array_init(&_trailers);
_op.data.recv_status_on_client.trailing_metadata = &_trailers;
if (handler) {
_handler = ^{
NSError *error = [NSError grpc_errorFromStatusCode:_statusCode details:_details];
NSDictionary *trailers = [NSDictionary grpc_dictionaryFromMetadataArray:_trailers];
handler(error, trailers);
};
}
} }
return self; return self;
} }
- (void)getOp:(grpc_op *)op {
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.status = &_statusCode;
op->data.recv_status_on_client.status_details = &_details;
op->data.recv_status_on_client.status_details_capacity = &_detailsCapacity;
op->data.recv_status_on_client.trailing_metadata = &_metadata;
}
- (void)finish {
if (_handler) {
NSError *error = [NSError grpc_errorFromStatusCode:_statusCode details:_details];
NSDictionary *trailers = [NSDictionary grpc_dictionaryFromMetadataArray:_metadata];
_handler(error, trailers);
}
}
- (void)dealloc { - (void)dealloc {
grpc_metadata_array_destroy(&_metadata); grpc_metadata_array_destroy(&_trailers);
gpr_free(_details); gpr_free(_details);
} }
...@@ -293,8 +251,8 @@ ...@@ -293,8 +251,8 @@
size_t nops = operations.count; size_t nops = operations.count;
grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op));
size_t i = 0; size_t i = 0;
for (id op in operations) { for (GRPCOperation *operation in operations) {
[op getOp:&ops_array[i++]]; ops_array[i++] = operation.op;
} }
grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops, grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops,
(__bridge_retained void *)(^(bool success){ (__bridge_retained void *)(^(bool success){
...@@ -305,14 +263,16 @@ ...@@ -305,14 +263,16 @@
return; return;
} }
} }
for (id<GRPCOp> operation in operations) { for (GRPCOperation *operation in operations) {
[operation finish]; [operation finish];
} }
})); }));
gpr_free(ops_array);
if (error != GRPC_CALL_OK) { if (error != GRPC_CALL_OK) {
[NSException raise:NSInternalInconsistencyException [NSException raise:NSInternalInconsistencyException
format:@"A precondition for calling grpc_call_start_batch wasn't met"]; format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i",
error];
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment