Skip to content

Commit

Permalink
[FIX] Fix random crashes on core data persistence #314
Browse files Browse the repository at this point in the history
[FIX] use_frameworks!
  • Loading branch information
Christoph Krey committed May 10, 2017
1 parent c80a475 commit d4e6d14
Show file tree
Hide file tree
Showing 90 changed files with 446 additions and 410 deletions.
3 changes: 2 additions & 1 deletion MQTTClient.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Pod::Spec.new do |mqttc|
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyDecoder.{h,m}",
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyEncoder.{h,m}",
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyTransport.{h,m}",
"MQTTClient/MQTTClient/MqttProperties.{h,m}",
"MQTTClient/MQTTClient/MQTTProperties.{h,m}",
"MQTTClient/MQTTClient/MQTTSession.{h,m}",
"MQTTClient/MQTTClient/MQTTSessionLegacy.{h,m}",
"MQTTClient/MQTTClient/MQTTSessionSynchron.{h,m}",
Expand All @@ -62,6 +62,7 @@ Pod::Spec.new do |mqttc|
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyDecoder.{h,m}",
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyEncoder.{h,m}",
"MQTTClient/MQTTClient/MQTTSSLSecurityPolicyTransport.{h,m}",
"MQTTClient/MQTTClient/MQTTProperties.{h,m}",
"MQTTClient/MQTTClient/MQTTSession.{h,m}",
"MQTTClient/MQTTClient/MQTTSessionLegacy.{h,m}",
"MQTTClient/MQTTClient/MQTTSessionSynchron.{h,m}",
Expand Down
150 changes: 102 additions & 48 deletions MQTTClient/MQTTClient.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion MQTTClient/MQTTClient/MQTTClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
Include this file to use MQTTClient classes in your application
@author Christoph Krey [email protected]
@author Christoph Krey [email protected]
@see http://mqtt.org
*/

Expand All @@ -18,6 +18,7 @@
#import <MQTTClient/MQTTSession.h>
#import <MQTTClient/MQTTSessionLegacy.h>
#import <MQTTClient/MQTTSessionSynchron.h>
#import <MQTTClient/MQTTProperties.h>
#import <MQTTClient/MQTTMessage.h>
#import <MQTTClient/MQTTTransport.h>
#import <MQTTClient/MQTTCFSocketTransport.h>
Expand Down
61 changes: 44 additions & 17 deletions MQTTClient/MQTTClient/MQTTCoreDataPersistence.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ @implementation MQTTCoreDataFlow
@synthesize context;
@synthesize object;

- (MQTTCoreDataFlow *)initWithContext:(NSManagedObjectContext *)c andObject:(id<MQTTFlow>)o
{
- (MQTTCoreDataFlow *)initWithContext:(NSManagedObjectContext *)c andObject:(id<MQTTFlow>)o {
self = [super init];
self.context = c;
self.object = o;
Expand All @@ -62,6 +61,7 @@ - (NSString *)clientId {
}
return _clientId;
}

- (void)setClientId:(NSString *)clientId {
if ([NSThread isMainThread]) {
object.clientId = clientId;
Expand All @@ -72,6 +72,7 @@ - (void)setClientId:(NSString *)clientId {
}];
}
}

- (NSNumber *)incomingFlag {
__block NSNumber *_incomingFlag;
if ([NSThread isMainThread]) {
Expand All @@ -83,16 +84,18 @@ - (NSNumber *)incomingFlag {
}
return _incomingFlag;
}

- (void)setIncomingFlag:(NSNumber *)incomingFlag {
if ([NSThread isMainThread]) {
object.incomingFlag = incomingFlag;
} else {

[context performBlockAndWait:^{
object.incomingFlag = incomingFlag;
}];
}
}


- (NSNumber *)retainedFlag {
__block NSNumber *_retainedFlag;
if ([NSThread isMainThread]) {
Expand All @@ -104,16 +107,17 @@ - (NSNumber *)retainedFlag {
}
return _retainedFlag;
}

- (void)setRetainedFlag:(NSNumber *)retainedFlag {
if ([NSThread isMainThread]) {
object.retainedFlag = retainedFlag;
} else {

[context performBlockAndWait:^{
object.retainedFlag = retainedFlag;
}];
}
}

- (NSNumber *)commandType {
__block NSNumber *_commandType;
if ([NSThread isMainThread]) {
Expand All @@ -125,6 +129,7 @@ - (NSNumber *)commandType {
}
return _commandType;
}

- (void)setCommandType:(NSNumber *)commandType {
if ([NSThread isMainThread]) {
object.commandType = commandType;
Expand All @@ -135,6 +140,7 @@ - (void)setCommandType:(NSNumber *)commandType {
}];
}
}

- (NSNumber *)qosLevel {
__block NSNumber *_qosLevel;
if ([NSThread isMainThread]) {
Expand All @@ -146,6 +152,7 @@ - (NSNumber *)qosLevel {
}
return _qosLevel;
}

- (void)setQosLevel:(NSNumber *)qosLevel {
if ([NSThread isMainThread]) {
object.qosLevel = qosLevel;
Expand All @@ -155,6 +162,7 @@ - (void)setQosLevel:(NSNumber *)qosLevel {
}];
}
}

- (NSNumber *)messageId {
__block NSNumber *_messageId;
if ([NSThread isMainThread]) {
Expand All @@ -166,6 +174,7 @@ - (NSNumber *)messageId {
}
return _messageId;
}

- (void)setMessageId:(NSNumber *)messageId {
if ([NSThread isMainThread]) {
object.messageId = messageId;
Expand All @@ -175,6 +184,7 @@ - (void)setMessageId:(NSNumber *)messageId {
}];
}
}

- (NSString *)topic {
__block NSString *_topic;
if ([NSThread isMainThread]) {
Expand All @@ -186,6 +196,7 @@ - (NSString *)topic {
}
return _topic;
}

- (void)setTopic:(NSString *)topic {
if ([NSThread isMainThread]) {
object.topic = topic;
Expand All @@ -195,6 +206,7 @@ - (void)setTopic:(NSString *)topic {
}];
}
}

- (NSData *)data {
__block NSData *_data;
if ([NSThread isMainThread]) {
Expand All @@ -206,6 +218,7 @@ - (NSData *)data {
}
return _data;
}

- (void)setData:(NSData *)data {
if ([NSThread isMainThread]) {
object.data = data;
Expand All @@ -215,6 +228,7 @@ - (void)setData:(NSData *)data {
}];
}
}

- (NSDate *)deadline {
__block NSDate *_deadline;
if ([NSThread isMainThread]) {
Expand All @@ -226,6 +240,7 @@ - (NSDate *)deadline {
}
return _deadline;
}

- (void)setDeadline:(NSDate *)deadline {
if ([NSThread isMainThread]) {
object.deadline = deadline;
Expand Down Expand Up @@ -327,8 +342,9 @@ - (void)deleteAllFlowsForClientId:(NSString *)clientId {
}

- (void)sync {
//Lock multithread execution
DDLogVerbose(@"lock sync %d", [NSThread isMainThread]);
@synchronized (lock) {
DDLogVerbose(@"locked sync %d", [NSThread isMainThread]);
if ([NSThread isMainThread]) {
[self internalSync];
} else {
Expand All @@ -344,12 +360,13 @@ - (void)sync {
[self internalParentSync];
}];
}
DDLogVerbose(@"unlocked sync %d", [NSThread isMainThread]);
}
}

- (void)internalSync {
if (self.managedObjectContext.hasChanges) {
DDLogVerbose(@"[MQTTPersistence] pre-sync: i%lu u%lu d%lu",
DDLogWarn(@"[MQTTPersistence] pre-sync: i%lu u%lu d%lu",
(unsigned long)self.managedObjectContext.insertedObjects.count,
(unsigned long)self.managedObjectContext.updatedObjects.count,
(unsigned long)self.managedObjectContext.deletedObjects.count
Expand Down Expand Up @@ -500,14 +517,15 @@ - (MQTTCoreDataFlow *)createFlowforClientId:(NSString *)clientId

#pragma mark - Core Data stack

- (NSManagedObjectContext *)managedObjectContext
{
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *managedObjectContext = [[NSThread currentThread].threadDictionary valueForKey:@"MQTTClient"];
if (managedObjectContext != nil) {
return managedObjectContext;
}


DDLogError(@"lock managedObjectcontext %d", [NSThread isMainThread]);
@synchronized (lock) {
DDLogError(@"locked managedObjectcontext %d", [NSThread isMainThread]);
if (parentManagedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
Expand All @@ -516,23 +534,29 @@ - (NSManagedObjectContext *)managedObjectContext
}
}

if ([[NSThread currentThread] isMainThread]) { // The main MOC is already associated to the main thread
if ([[NSThread currentThread] isMainThread]) {
// The main MOC is already associated to the main thread
[[NSThread currentThread].threadDictionary setObject:parentManagedObjectContext forKey:@"MQTTClient"];
DDLogVerbose(@"unlocked managedObjectcontext %d", [NSThread isMainThread]);
return parentManagedObjectContext;
} else { // Only create a new managed object context if in a background thread
} else {
// Only create a new managed object context if in a background thread
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[managedObjectContext setParentContext:parentManagedObjectContext];

[[NSThread currentThread].threadDictionary setObject:managedObjectContext forKey:@"MQTTClient"];

DDLogVerbose(@"unlocked managedObjectcontext %d", [NSThread isMainThread]);
return managedObjectContext;
}
}
}

- (NSManagedObjectModel *)managedObjectModel
{
- (NSManagedObjectModel *)managedObjectModel {
DDLogVerbose(@"lock managedObjectModel %d", [NSThread isMainThread]);
@synchronized (lock) {
DDLogVerbose(@"locked managedObjectModel %d", [NSThread isMainThread]);
if (managedObjectModel != nil) {
DDLogVerbose(@"unlocked managedObjectModel %d", [NSThread isMainThread]);
return managedObjectModel;
}

Expand Down Expand Up @@ -605,14 +629,17 @@ - (NSManagedObjectModel *)managedObjectModel
[entities addObject:entityDescription];
[managedObjectModel setEntities:entities];

DDLogVerbose(@"unlocked managedObjectModel %d", [NSThread isMainThread]);
return managedObjectModel;
}
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
DDLogVerbose(@"lock persistentStoreCoordinator %d", [NSThread isMainThread]);
@synchronized (lock) {
DDLogVerbose(@"locked persistentStoreCoordinator %d", [NSThread isMainThread]);
if (persistentStoreCoordinator != nil) {
DDLogVerbose(@"unlocked persistentStoreCoordinator %d", [NSThread isMainThread]);
return persistentStoreCoordinator;
}

Expand All @@ -638,7 +665,7 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
DDLogError(@"[MQTTPersistence] managedObjectContext save: %@", error);
persistentStoreCoordinator = nil;
}

DDLogVerbose(@"unlocked persistentStoreCoordinator %d", [NSThread isMainThread]);
return persistentStoreCoordinator;
}
}
Expand Down
54 changes: 23 additions & 31 deletions MQTTClient/MQTTClient/MQTTLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,28 @@
// Copyright © 2016-2017 Christoph Krey. All rights reserved.
//

#ifndef MQTTLog_h

#define MQTTLog_h


#ifdef LUMBERJACK
#define LOG_LEVEL_DEF ddLogLevel
#import <CocoaLumberjack/CocoaLumberjack.h>
#ifndef myLogLevel
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif
#else
static const DDLogLevel ddLogLevel = myLogLevel;
#endif
#define LOG_LEVEL_DEF ddLogLevel
#import <CocoaLumberjack/CocoaLumberjack.h>
#ifndef myLogLevel
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#else
#ifdef DEBUG
#define DDLogVerbose NSLog
#define DDLogWarn NSLog
#define DDLogInfo NSLog
#define DDLogError NSLog
#else
#define DDLogVerbose(...)
#define DDLogWarn(...)
#define DDLogInfo(...)
#define DDLogError(...)
#endif
#endif


#endif /* MQTTLog_h */
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif /* DEBUG */
#else
static const DDLogLevel ddLogLevel = myLogLevel;
#endif /* myLogLevel */
#else
#ifdef DEBUG
#define DDLogVerbose NSLog
#define DDLogWarn NSLog
#define DDLogInfo NSLog
#define DDLogError NSLog
#else
#define DDLogVerbose(...)
#define DDLogWarn(...)
#define DDLogInfo(...)
#define DDLogError(...)
#endif /* DEBUG */
#endif /* LUMBERJACK */
4 changes: 2 additions & 2 deletions MQTTClient/MQTTClient/MQTTMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//

#import <Foundation/Foundation.h>
#import "MqttProperties.h"
@class MQTTProperties;

/**
Enumeration of MQTT Quality of Service levels
Expand Down Expand Up @@ -66,7 +66,7 @@ typedef NS_ENUM(UInt8, MQTTCommandType) {
@property (nonatomic) UInt16 mid;
@property (strong, nonatomic) NSData *data;
@property (strong, nonatomic) NSNumber *returnCode;
@property (strong, nonatomic) MqttProperties *properties;
@property (strong, nonatomic) MQTTProperties *properties;

/**
Enumeration of MQTT return codes
Expand Down
3 changes: 2 additions & 1 deletion MQTTClient/MQTTClient/MQTTMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//

#import "MQTTMessage.h"
#import "MQTTProperties.h"

#import "MQTTLog.h"

Expand Down Expand Up @@ -642,7 +643,7 @@ + (MQTTMessage *)messageFromData:(NSData *)data protocolLevel:(MQTTProtocolVersi
const UInt8 *bytes = message.data.bytes;
message.returnCode = [NSNumber numberWithInt:bytes[1]];
if (protocolLevel == MQTTProtocolVersion50) {
message.properties = [[MqttProperties alloc] initFromData:
message.properties = [[MQTTProperties alloc] initFromData:
[message.data subdataWithRange:NSMakeRange(2, message.data.length - 2)]];
}
}
Expand Down
Loading

0 comments on commit d4e6d14

Please sign in to comment.