From 70d8abd59f71d147a39e932c31f6d8b34516039d Mon Sep 17 00:00:00 2001 From: asorrin-msft Date: Tue, 19 Jan 2016 14:48:28 -0800 Subject: [PATCH] This is a combination of two bug fixes. First, it changes the framework build script to be more robust - you no longer have to explicitly build the library before building the framework target. Second, it fixes a potential race condition in the library, where a request can hang forever, never calling the callback with the request result. --- .../Azure Storage Client Library.xcodeproj/project.pbxproj | 3 +-- .../Azure Storage Client Library/AZSExecutor.m | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/Azure Storage Client Library/Azure Storage Client Library.xcodeproj/project.pbxproj b/Lib/Azure Storage Client Library/Azure Storage Client Library.xcodeproj/project.pbxproj index 0f506cd..f4fa394 100644 --- a/Lib/Azure Storage Client Library/Azure Storage Client Library.xcodeproj/project.pbxproj +++ b/Lib/Azure Storage Client Library/Azure Storage Client Library.xcodeproj/project.pbxproj @@ -498,7 +498,6 @@ buildPhases = ( BE45103C1A9D252300C3F971 /* Sources */, BE45103D1A9D252300C3F971 /* Frameworks */, - BE45103E1A9D252300C3F971 /* CopyFiles */, B082D17C1BB0D23800A39C18 /* Headers */, B082D1741BAA94BE00A39C18 /* Build Framework */, ); @@ -597,7 +596,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\necho \"xxxxx\"\n\n# If we're already inside this script then die\nif [ -n \"$RW_MULTIPLATFORM_BUILD_IN_PROGRESS\" ]; then\nexit 0\nfi\nexport RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1\n\nRW_FRAMEWORK_NAME=${PROJECT_NAME}\nRW_INPUT_STATIC_LIB=\"lib${PROJECT_NAME}.a\"\nRW_FRAMEWORK_LOCATION=\"${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework\"\n\nfunction build_static_library {\n # Will rebuild the static library as specified\n # build_static_library sdk\n xcrun xcodebuild -project \"${PROJECT_FILE_PATH}\" \\\n -target \"${TARGET_NAME}\" \\\n -configuration \"${CONFIGURATION}\" \\\n -sdk \"${1}\" \\\n ONLY_ACTIVE_ARCH=NO \\\n BUILD_DIR=\"${BUILD_DIR}\" \\\n OBJROOT=\"${OBJROOT}\" \\\n BUILD_ROOT=\"${BUILD_ROOT}\" \\\n SYMROOT=\"${SYMROOT}\" $ACTION\n}\n\nfunction make_fat_library {\n # Will smash 2 static libs together\n # make_fat_library in1 in2 out\n xcrun lipo -create \"${1}\" \"${2}\" -output \"${3}\"\n}\n\n# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]; then\nRW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\necho \"Could not find platform name from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 2 - Extract the version from the SDK\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]; then\nRW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\necho \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 3 - Determine the other platform\nif [ \"$RW_SDK_PLATFORM\" == \"iphoneos\" ]; then\nRW_OTHER_PLATFORM=iphonesimulator\nelse\nRW_OTHER_PLATFORM=iphoneos\nfi\n\n# 4 - Find the build directory\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$RW_SDK_PLATFORM$ ]]; then\nRW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}\"\nelse\necho \"Could not find other platform build directory.\"\nexit 1\nfi\n\n# Build the other platform.\nbuild_static_library \"${RW_OTHER_PLATFORM}${RW_SDK_VERSION}\"\n\n# If we're currently building for iphonesimulator, then need to rebuild\n# to ensure that we get both i386 and x86_64\nif [ \"$RW_SDK_PLATFORM\" == \"iphonesimulator\" ]; then\nbuild_static_library \"${SDK_NAME}\"\nfi\n\n# Join the 2 static libs into 1 and push into the .framework\nmake_fat_library \"${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\"\n\necho \"hello\"\n\n# Ensure that the framework is present in both platform's build directories\ncp -a \"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Copy the framework to the user's desktop\nditto \"${RW_FRAMEWORK_LOCATION}\" \"${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework\""; + shellScript = "set -e\n\n# If we're already inside this script then die\nif [ -n \"$RW_MULTIPLATFORM_BUILD_IN_PROGRESS\" ]; then\nexit 0\nfi\nexport RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1\n\nRW_FRAMEWORK_NAME=${PROJECT_NAME}\nRW_INPUT_STATIC_LIB=\"lib${PROJECT_NAME}.a\"\nRW_FRAMEWORK_LOCATION=\"${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework\"\n\nfunction build_static_library {\n echo \"CONFIGURATION = ${CONFIGURATION}\"\n # Will rebuild the static library as specified\n # build_static_library sdk\n xcrun xcodebuild -project \"${PROJECT_FILE_PATH}\" \\\n -target \"Azure Storage Client Library\" \\\n -configuration \"${CONFIGURATION}\" \\\n -sdk \"${1}\" -verbose \\\n ONLY_ACTIVE_ARCH=NO \\\n BUILD_DIR=\"${BUILD_DIR}\" \\\n OBJROOT=\"${OBJROOT}\" \\\n BUILD_ROOT=\"${BUILD_ROOT}\" \\\n SYMROOT=\"${SYMROOT}\" $ACTION >&1\n}\n\nfunction make_fat_library {\n # Will smash 2 static libs together\n # make_fat_library in1 in2 out\n xcrun lipo -create \"${1}\" \"${2}\" -output \"${3}\"\n}\n\n# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]; then\nRW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\necho \"Could not find platform name from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 2 - Extract the version from the SDK\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]; then\nRW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\necho \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 3 - Determine the other platform\nif [ \"$RW_SDK_PLATFORM\" == \"iphoneos\" ]; then\nRW_OTHER_PLATFORM=iphonesimulator\nelse\nRW_OTHER_PLATFORM=iphoneos\nfi\n\n# 4 - Find the build directory\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$RW_SDK_PLATFORM$ ]]; then\nRW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}\"\nelse\necho \"Could not find other platform build directory.\"\nexit 1\nfi\n\n# Build the library\nbuild_static_library \"${SDK_NAME}\"\n\n# Build the other platform.\nbuild_static_library \"${RW_OTHER_PLATFORM}${RW_SDK_VERSION}\"\n\n\n# Join the 2 static libs into 1 and push into the .framework\nmake_fat_library \"${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\"\n\necho \"hello\"\n\n# Ensure that the framework is present in both platform's build directories\ncp -a \"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Copy the framework to the user's desktop\nditto \"${RW_FRAMEWORK_LOCATION}\" \"${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework\""; }; /* End PBXShellScriptBuildPhase section */ diff --git a/Lib/Azure Storage Client Library/Azure Storage Client Library/AZSExecutor.m b/Lib/Azure Storage Client Library/Azure Storage Client Library/AZSExecutor.m index dfb9ffd..4258d0f 100644 --- a/Lib/Azure Storage Client Library/Azure Storage Client Library/AZSExecutor.m +++ b/Lib/Azure Storage Client Library/Azure Storage Client Library/AZSExecutor.m @@ -364,7 +364,7 @@ -(void)execute // TODO: make this static, so that we're not querying the OS each time NSString *operationSystemVersionString = [NSProcessInfo processInfo].operatingSystemVersionString; - [self.request setValue:[NSString stringWithFormat:@"Azure-Storage/0.1.1-preview (iOS %@)",operationSystemVersionString] forHTTPHeaderField:@"User-Agent"]; + [self.request setValue:[NSString stringWithFormat:@"Azure-Storage/0.1.2-preview (iOS %@)",operationSystemVersionString] forHTTPHeaderField:@"User-Agent"]; // Add the user headers, if they exist. if (self.operationContext.userHeaders) @@ -448,6 +448,7 @@ -(void)createAndSpinRunloopWithOutputStream:(id)outputStream @autoreleasepool { self.runLoopForDownload = [NSRunLoop currentRunLoop]; [outputStream scheduleInRunLoop:self.runLoopForDownload forMode:NSDefaultRunLoopMode]; + [self.outputStream open]; dispatch_semaphore_signal(self.semaphoreForRunloopCreation); // TODO: Make the below timeout value for the runloop configurable. @@ -516,6 +517,7 @@ -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataT self.runLoopForDownload = self.requestOptions.runLoopForDownload; if (self.runLoopForDownload == nil) { + // In this case, we will open the stream inside the createAndSpinRunloopWithOutputStream method. self.semaphoreForRunloopCreation = dispatch_semaphore_create(0); [NSThread detachNewThreadSelector:@selector(createAndSpinRunloopWithOutputStream:) toTarget:self withObject:self.outputStream]; @@ -525,10 +527,10 @@ -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataT else { [self.outputStream scheduleInRunLoop:self.runLoopForDownload forMode:NSDefaultRunLoopMode]; + [self.outputStream open]; } - [self.outputStream open]; completionHandler(NSURLSessionResponseAllow); }