Thrift-1340: Add support of ARC to Objective-C
Client: Objective-c
Patch: Hirano Satoshi
Adds -objc-arc flag to compiler and if used removes the retain/release/autorelease from generated code
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1210732 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cocoa/src/TApplicationException.m b/lib/cocoa/src/TApplicationException.m
index 7068753..66c2f2b 100644
--- a/lib/cocoa/src/TApplicationException.m
+++ b/lib/cocoa/src/TApplicationException.m
@@ -19,6 +19,7 @@
#import "TApplicationException.h"
#import "TProtocolUtil.h"
+#import "TObjective-C.h"
@implementation TApplicationException
@@ -124,7 +125,7 @@
reason: (NSString *) reason
{
return [[[TApplicationException alloc] initWithType: type
- reason: reason] autorelease];
+ reason: reason] autorelease_stub];
}
@end
diff --git a/lib/cocoa/src/TException.m b/lib/cocoa/src/TException.m
index 7c84199..0160e3b 100644
--- a/lib/cocoa/src/TException.m
+++ b/lib/cocoa/src/TException.m
@@ -18,6 +18,7 @@
*/
#import "TException.h"
+#import "TObjective-C.h"
@implementation TException
diff --git a/lib/cocoa/src/TObjective-C.h b/lib/cocoa/src/TObjective-C.h
new file mode 100644
index 0000000..9c0831d
--- /dev/null
+++ b/lib/cocoa/src/TObjective-C.h
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * TObjective-C.h is for supporting coexistence of both the ARC (Automatic
+ * Reference Counting) mode and the Non-ARC mode of Objective-C
+ * in the same source code.
+ *
+ * 2011/11/14 HIRANO Satoshi (AIST, Japan)
+ *
+ * Before:
+ *
+ * var = [aObject retain];
+ * [aObject release];
+ * [aObject autorelease];
+ * [super dealloc];
+ * CFFunction(obj);
+ *
+ * ARC and Non-ARC compatible:
+ *
+ * #import "TObjective-C.h"
+ * var = [aObject retain_stub];
+ * [aObject release_stub];
+ * [aObject autorelease_stub];
+ * [super dealloc_stub];
+ * CFFunction(bridge_stub obj);
+ *
+ * Don't use retain_stub for @property(retain).
+ * Use NSAutoreleasePool like this:
+ * #if __has_feature(objc_arc)
+ * @autoreleasepool {
+ * // code
+ * }
+ * #else
+ * NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init...
+ * // code
+ * [pool release];
+ * #endif
+ */
+
+
+#if !defined(retain_stub)
+#if __has_feature(objc_arc)
+#define retain_stub self
+#define autorelease_stub self
+#define release_stub self
+#define dealloc_stub self
+#define bridge_stub __bridge
+#else
+#define retain_stub retain
+#define autorelease_stub autorelease
+#define release_stub release
+#define dealloc_stub dealloc
+#define bridge_stub
+#endif
+#endif
diff --git a/lib/cocoa/src/TSharedProcessorFactory.m b/lib/cocoa/src/TSharedProcessorFactory.m
index b38e73a..a0007c0 100644
--- a/lib/cocoa/src/TSharedProcessorFactory.m
+++ b/lib/cocoa/src/TSharedProcessorFactory.m
@@ -19,6 +19,7 @@
#import "TSharedProcessorFactory.h"
+#import "TObjective-C.h"
@implementation TSharedProcessorFactory
@@ -31,21 +32,21 @@
return nil;
}
- mSharedProcessor = [sharedProcessor retain];
+ mSharedProcessor = [sharedProcessor retain_stub];
return self;
}
- (void) dealloc
{
- [mSharedProcessor release];
- [super dealloc];
+ [mSharedProcessor release_stub];
+ [super dealloc_stub];
}
- (id<TProcessor>) processorForTransport: (id<TTransport>) transport
{
- return [[mSharedProcessor retain] autorelease];
+ return [[mSharedProcessor retain_stub] autorelease_stub];
}
@end
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.m b/lib/cocoa/src/protocol/TBinaryProtocol.m
index b272716..f269aaa 100644
--- a/lib/cocoa/src/protocol/TBinaryProtocol.m
+++ b/lib/cocoa/src/protocol/TBinaryProtocol.m
@@ -19,6 +19,7 @@
#import "TBinaryProtocol.h"
#import "TProtocolException.h"
+#import "TObjective-C.h"
int32_t VERSION_1 = 0x80010000;
int32_t VERSION_MASK = 0xffff0000;
@@ -56,7 +57,7 @@
strictWrite: (BOOL) strictWrite
{
self = [super init];
- mTransport = [transport retain];
+ mTransport = [transport retain_stub];
mStrictRead = strictRead;
mStrictWrite = strictWrite;
return self;
@@ -77,8 +78,8 @@
- (void) dealloc
{
- [mTransport release];
- [super dealloc];
+ [mTransport release_stub];
+ [super dealloc_stub];
}
diff --git a/lib/cocoa/src/server/TSocketServer.m b/lib/cocoa/src/server/TSocketServer.m
index 5f7fa3c..057f41f 100644
--- a/lib/cocoa/src/server/TSocketServer.m
+++ b/lib/cocoa/src/server/TSocketServer.m
@@ -22,6 +22,7 @@
#import "TNSFileHandleTransport.h"
#import "TProtocol.h"
#import "TTransportException.h"
+#import "TObjective-C.h"
#import <sys/socket.h>
#include <netinet/in.h>
@@ -40,9 +41,9 @@
{
self = [super init];
- mInputProtocolFactory = [protocolFactory retain];
- mOutputProtocolFactory = [protocolFactory retain];
- mProcessorFactory = [processorFactory retain];
+ mInputProtocolFactory = [protocolFactory retain_stub];
+ mOutputProtocolFactory = [protocolFactory retain_stub];
+ mProcessorFactory = [processorFactory retain_stub];
// create a socket.
int fd = -1;
@@ -60,7 +61,7 @@
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
NSData *address = [NSData dataWithBytes:&addr length:sizeof(addr)];
- if (CFSocketSetAddress(socket, (CFDataRef)address) != kCFSocketSuccess) {
+ if (CFSocketSetAddress(socket, (bridge_stub CFDataRef)address) != kCFSocketSuccess) {
CFSocketInvalidate(socket);
CFRelease(socket);
NSLog(@"*** Could not bind to address");
@@ -96,11 +97,11 @@
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObject: self];
- [mInputProtocolFactory release];
- [mOutputProtocolFactory release];
- [mProcessorFactory release];
- [mSocketFileHandle release];
- [super dealloc];
+ [mInputProtocolFactory release_stub];
+ [mOutputProtocolFactory release_stub];
+ [mProcessorFactory release_stub];
+ [mSocketFileHandle release_stub];
+ [super dealloc_stub];
}
@@ -119,6 +120,38 @@
- (void) handleClientConnection: (NSFileHandle *) clientSocket
{
+#if __has_feature(objc_arc)
+ @autoreleasepool {
+ TNSFileHandleTransport * transport = [[TNSFileHandleTransport alloc] initWithFileHandle: clientSocket];
+ id<TProcessor> processor = [mProcessorFactory processorForTransport: transport];
+
+ id <TProtocol> inProtocol = [mInputProtocolFactory newProtocolOnTransport: transport];
+ id <TProtocol> outProtocol = [mOutputProtocolFactory newProtocolOnTransport: transport];
+
+ @try {
+ BOOL result = NO;
+ do {
+ @autoreleasepool {
+ result = [processor processOnInputProtocol: inProtocol outputProtocol: outProtocol];
+ }
+ } while (result);
+ }
+ @catch (TTransportException * te) {
+ //NSLog(@"Caught transport exception, abandoning client connection: %@", te);
+ }
+
+ NSNotification * n = [NSNotification notificationWithName: kTSocketServer_ClientConnectionFinishedForProcessorNotification
+ object: self
+ userInfo: [NSDictionary dictionaryWithObjectsAndKeys:
+ processor,
+ kTSocketServer_ProcessorKey,
+ transport,
+ kTSockerServer_TransportKey,
+ nil]];
+ [[NSNotificationCenter defaultCenter] performSelectorOnMainThread: @selector(postNotification:) withObject: n waitUntilDone: YES];
+
+ }
+#else
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
TNSFileHandleTransport * transport = [[TNSFileHandleTransport alloc] initWithFileHandle: clientSocket];
@@ -150,6 +183,7 @@
[[NSNotificationCenter defaultCenter] performSelectorOnMainThread: @selector(postNotification:) withObject: n waitUntilDone: YES];
[pool release];
+#endif
}
diff --git a/lib/cocoa/src/transport/THTTPClient.m b/lib/cocoa/src/transport/THTTPClient.m
index 1eaa859..5617d45 100644
--- a/lib/cocoa/src/transport/THTTPClient.m
+++ b/lib/cocoa/src/transport/THTTPClient.m
@@ -19,6 +19,7 @@
#import "THTTPClient.h"
#import "TTransportException.h"
+#import "TObjective-C.h"
@implementation THTTPClient
@@ -26,7 +27,7 @@
- (void) setupRequest
{
if (mRequest != nil) {
- [mRequest release];
+ [mRequest release_stub];
}
// set up our request object that we'll use for each request
@@ -67,9 +68,9 @@
mTimeout = timeout;
if (userAgent) {
- mUserAgent = [userAgent retain];
+ mUserAgent = [userAgent retain_stub];
}
- mURL = [aURL retain];
+ mURL = [aURL retain_stub];
[self setupRequest];
@@ -82,8 +83,8 @@
- (void) setURL: (NSURL *) aURL
{
- [aURL retain];
- [mURL release];
+ [aURL retain_stub];
+ [mURL release_stub];
mURL = aURL;
[self setupRequest];
@@ -92,12 +93,12 @@
- (void) dealloc
{
- [mURL release];
- [mUserAgent release];
- [mRequest release];
- [mRequestData release];
- [mResponseData release];
- [super dealloc];
+ [mURL release_stub];
+ [mUserAgent release_stub];
+ [mRequest release_stub];
+ [mRequestData release_stub];
+ [mResponseData release_stub];
+ [super dealloc_stub];
}
@@ -151,8 +152,8 @@
}
// phew!
- [mResponseData release];
- mResponseData = [responseData retain];
+ [mResponseData release_stub];
+ mResponseData = [responseData retain_stub];
mResponseDataOffset = 0;
}
diff --git a/lib/cocoa/src/transport/TMemoryBuffer.m b/lib/cocoa/src/transport/TMemoryBuffer.m
index 869010a..c3801c7 100644
--- a/lib/cocoa/src/transport/TMemoryBuffer.m
+++ b/lib/cocoa/src/transport/TMemoryBuffer.m
@@ -19,6 +19,7 @@
#import "TMemoryBuffer.h"
#import "TTransportException.h"
+#import "TObjective-C.h"
#define GARBAGE_BUFFER_SIZE 4096 // 4KiB
@@ -61,11 +62,11 @@
}
- (NSData *)getBuffer {
- return [[mBuffer copy] autorelease];
+ return [[mBuffer copy] autorelease_stub];
}
- (void)dealloc {
- [mBuffer release];
- [super dealloc];
+ [mBuffer release_stub];
+ [super dealloc_stub];
}
@end
diff --git a/lib/cocoa/src/transport/TNSFileHandleTransport.m b/lib/cocoa/src/transport/TNSFileHandleTransport.m
index b218218..0ff200b 100644
--- a/lib/cocoa/src/transport/TNSFileHandleTransport.m
+++ b/lib/cocoa/src/transport/TNSFileHandleTransport.m
@@ -20,6 +20,7 @@
#import "TNSFileHandleTransport.h"
#import "TTransportException.h"
+#import "TObjective-C.h"
@implementation TNSFileHandleTransport
@@ -36,17 +37,17 @@
{
self = [super init];
- mInputFileHandle = [inputFileHandle retain];
- mOutputFileHandle = [outputFileHandle retain];
+ mInputFileHandle = [inputFileHandle retain_stub];
+ mOutputFileHandle = [outputFileHandle retain_stub];
return self;
}
- (void) dealloc {
- [mInputFileHandle release];
- [mOutputFileHandle release];
- [super dealloc];
+ [mInputFileHandle release_stub];
+ [mOutputFileHandle release_stub];
+ [super dealloc_stub];
}
@@ -66,9 +67,10 @@
}
-- (void) write: (uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
+- (void) write: (const uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
{
- NSData * dataObject = [[NSData alloc] initWithBytesNoCopy: data+offset
+ void *pos = (void *) data + offset;
+ NSData * dataObject = [[NSData alloc] initWithBytesNoCopy: pos // data+offset
length: length
freeWhenDone: NO];
@@ -79,7 +81,7 @@
reason: [NSString stringWithFormat: @"%s: Unable to write data: %@", __PRETTY_FUNCTION__, e]];
}
- [dataObject release];
+ [dataObject release_stub];
}
diff --git a/lib/cocoa/src/transport/TNSStreamTransport.m b/lib/cocoa/src/transport/TNSStreamTransport.m
index 1d4cfee..265e0ba 100644
--- a/lib/cocoa/src/transport/TNSStreamTransport.m
+++ b/lib/cocoa/src/transport/TNSStreamTransport.m
@@ -19,6 +19,7 @@
#import "TNSStreamTransport.h"
#import "TTransportException.h"
+#import "TObjective-C.h"
@implementation TNSStreamTransport
@@ -26,9 +27,9 @@
- (id) initWithInputStream: (NSInputStream *) input
outputStream: (NSOutputStream *) output
{
- [super init];
- mInput = [input retain];
- mOutput = [output retain];
+ self = [super init];
+ mInput = [input retain_stub];
+ mOutput = [output retain_stub];
return self;
}
@@ -44,9 +45,9 @@
- (void) dealloc
{
- [mInput release];
- [mOutput release];
- [super dealloc];
+ [mInput release_stub];
+ [mOutput release_stub];
+ [super dealloc_stub];
}
@@ -65,7 +66,7 @@
}
-- (void) write: (uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
+- (void) write: (const uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
{
int got = 0;
int result = 0;
diff --git a/lib/cocoa/src/transport/TSocketClient.h b/lib/cocoa/src/transport/TSocketClient.h
index 0ea957d..372850f 100644
--- a/lib/cocoa/src/transport/TSocketClient.h
+++ b/lib/cocoa/src/transport/TSocketClient.h
@@ -20,7 +20,11 @@
#import <Foundation/Foundation.h>
#import "TNSStreamTransport.h"
-@interface TSocketClient : TNSStreamTransport {
+@interface TSocketClient : TNSStreamTransport
+#if TARGET_OS_IPHONE || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+<NSStreamDelegate>
+#endif
+{
}
- (id) initWithHostname: (NSString *) hostname
diff --git a/lib/cocoa/src/transport/TSocketClient.m b/lib/cocoa/src/transport/TSocketClient.m
index 74d4af9..256ecf3 100644
--- a/lib/cocoa/src/transport/TSocketClient.m
+++ b/lib/cocoa/src/transport/TSocketClient.m
@@ -17,6 +17,7 @@
* under the License.
*/
#import "TSocketClient.h"
+#import "TObjective-C.h"
#if !TARGET_OS_IPHONE
#import <CoreServices/CoreServices.h>
@@ -33,22 +34,24 @@
NSOutputStream * outputStream = NULL;
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
- CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)hostname, port, &readStream, &writeStream);
+ CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (bridge_stub CFStringRef)hostname, port, &readStream, &writeStream);
if (readStream && writeStream) {
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
- inputStream = (NSInputStream *)readStream;
- [inputStream retain];
+ inputStream = (bridge_stub NSInputStream *)readStream;
+ [inputStream retain_stub];
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
- outputStream = (NSOutputStream *)writeStream;
- [outputStream retain];
+ outputStream = (bridge_stub NSOutputStream *)writeStream;
+ [outputStream retain_stub];
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream open];
+ CFRelease(readStream);
+ CFRelease(writeStream);
}
self = [super initWithInputStream: inputStream outputStream: outputStream];
diff --git a/lib/cocoa/src/transport/TTransportException.m b/lib/cocoa/src/transport/TTransportException.m
index aa67149..43cdfbd 100644
--- a/lib/cocoa/src/transport/TTransportException.m
+++ b/lib/cocoa/src/transport/TTransportException.m
@@ -18,6 +18,7 @@
*/
#import "TTransportException.h"
+#import "TObjective-C.h"
@implementation TTransportException