Skip to content
This repository
Browse code

Merging latest changes from CocoaLumberjack project.

  • Loading branch information...
commit ce1b08962712026ad674abfc9052252e89788211 1 parent a4ee2b2
Robbie Hanson authored
17 Vendor/CocoaLumberjack/DDFileLogger.m
@@ -203,17 +203,18 @@ - (NSString *)defaultLogsDirectory
203 203 {
204 204 #if TARGET_OS_IPHONE
205 205 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
206   - NSString *baseDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
  206 + NSString *baseDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
  207 + NSString *logsDirectory = [baseDir stringByAppendingPathComponent:@"Logs"];
  208 +
207 209 #else
208   - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
209   - NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
210   -
211 210 NSString *appName = [[NSProcessInfo processInfo] processName];
212   -
213   - NSString *baseDir = [basePath stringByAppendingPathComponent:appName];
  211 + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
  212 + NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
  213 + NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName];
  214 +
214 215 #endif
215   -
216   - return [baseDir stringByAppendingPathComponent:@"Logs"];
  216 +
  217 + return logsDirectory;
217 218 }
218 219
219 220 - (NSString *)logsDirectory
3  Vendor/CocoaLumberjack/DDLog.h
@@ -534,6 +534,9 @@ NSString *ExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
534 534 const char *function;
535 535 int lineNumber;
536 536 mach_port_t machThreadID;
  537 +#if GCD_MAYBE_AVAILABLE
  538 + char *queueLabel;
  539 +#endif
537 540
538 541 // The private variables below are only calculated if needed.
539 542 // You should use the public methods to access this information.
350 Vendor/CocoaLumberjack/DDLog.m
@@ -42,13 +42,17 @@
42 42
43 43 #define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
44 44
  45 +
45 46 #if GCD_MAYBE_AVAILABLE
46   -struct LoggerNode {
47   - id <DDLogger> logger;
  47 +@interface DDLoggerNode : NSObject {
  48 +@public
  49 + id <DDLogger> logger;
48 50 dispatch_queue_t loggerQueue;
49   - struct LoggerNode * next;
50   -};
51   -typedef struct LoggerNode LoggerNode;
  51 +}
  52 +
  53 ++ (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue;
  54 +
  55 +@end
52 56 #endif
53 57
54 58
@@ -68,6 +72,10 @@ + (void)lt_flush;
68 72
69 73 @implementation DDLog
70 74
  75 + // An array used to manage all the individual loggers.
  76 + // The array is only modified on the loggingQueue/loggingThread.
  77 + static NSMutableArray *loggers;
  78 +
71 79 #if GCD_MAYBE_AVAILABLE
72 80
73 81 // All logging statements are added to the same queue to ensure FIFO operation.
@@ -77,10 +85,6 @@ @implementation DDLog
77 85 // Each logger has it's own associated queue, and a dispatch group is used for synchrnoization.
78 86 static dispatch_group_t loggingGroup;
79 87
80   - // A linked list is used to manage all the individual loggers.
81   - // Each item in the linked list also includes the loggers associated dispatch queue.
82   - static LoggerNode *loggerNodes;
83   -
84 88 // In order to prevent to queue from growing infinitely large,
85 89 // a maximum size is enforced (LOG_MAX_QUEUE_SIZE).
86 90 static dispatch_semaphore_t queueSemaphore;
@@ -95,10 +99,6 @@ @implementation DDLog
95 99 // All logging statements are queued onto the same thread to ensure FIFO operation.
96 100 static NSThread *loggingThread;
97 101
98   - // An array is used to manage all the individual loggers.
99   - // The array is only modified on the loggingThread.
100   - static NSMutableArray *loggers;
101   -
102 102 // In order to prevent to queue from growing infinitely large,
103 103 // a maximum size is enforced (LOG_MAX_QUEUE_SIZE).
104 104 static int32_t queueSize; // Incremented and decremented locklessly using OSAtomic operations
@@ -122,6 +122,8 @@ + (void)initialize
122 122 {
123 123 initialized = YES;
124 124
  125 + loggers = [[NSMutableArray alloc] initWithCapacity:4];
  126 +
125 127 if (IS_GCD_AVAILABLE)
126 128 {
127 129 #if GCD_MAYBE_AVAILABLE
@@ -131,8 +133,6 @@ + (void)initialize
131 133 loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL);
132 134 loggingGroup = dispatch_group_create();
133 135
134   - loggerNodes = NULL;
135   -
136 136 queueSemaphore = dispatch_semaphore_create(LOG_MAX_QUEUE_SIZE);
137 137
138 138 // Figure out how many processors are available.
@@ -162,8 +162,6 @@ + (void)initialize
162 162 loggingThread = [[NSThread alloc] initWithTarget:self selector:@selector(lt_main:) object:nil];
163 163 [loggingThread start];
164 164
165   - loggers = [[NSMutableArray alloc] initWithCapacity:4];
166   -
167 165 queueSize = 0;
168 166
169 167 condition = [[NSCondition alloc] init];
@@ -539,6 +537,50 @@ + (BOOL)isRegisteredClass:(Class)class
539 537 SEL getterSel = @selector(ddLogLevel);
540 538 SEL setterSel = @selector(ddSetLogLevel:);
541 539
  540 +#if TARGET_OS_IPHONE
  541 +
  542 + // Issue #6 - Crashes on iOS 4.2.1 and iPhone 4
  543 + //
  544 + // Crash caused by class_getClassMethod(2).
  545 + //
  546 + // "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until
  547 + // users had VoiceOver enabled [...]. I was able to work around it by searching the
  548 + // result of class_copyMethodList() instead of calling class_getClassMethod()"
  549 +
  550 + unsigned int methodCount, i;
  551 + Method *methodList = class_copyMethodList(object_getClass(class), &methodCount);
  552 +
  553 + if (methodList != NULL)
  554 + {
  555 + BOOL getterFound = NO;
  556 + BOOL setterFound = NO;
  557 +
  558 + for (i = 0; i < methodCount; ++i)
  559 + {
  560 + SEL currentSel = method_getName(methodList[i]);
  561 +
  562 + if (currentSel == getterSel)
  563 + {
  564 + getterFound = YES;
  565 + }
  566 + else if (currentSel == setterSel)
  567 + {
  568 + setterFound = YES;
  569 + }
  570 +
  571 + if (getterFound && setterFound)
  572 + {
  573 + return YES;
  574 + }
  575 + }
  576 +
  577 + free(methodList);
  578 + }
  579 +
  580 + return NO;
  581 +
  582 +#else
  583 +
542 584 Method getter = class_getClassMethod(class, getterSel);
543 585 Method setter = class_getClassMethod(class, setterSel);
544 586
@@ -548,6 +590,8 @@ + (BOOL)isRegisteredClass:(Class)class
548 590 }
549 591
550 592 return NO;
  593 +
  594 +#endif
551 595 }
552 596
553 597 + (NSArray *)registeredClasses
@@ -671,24 +715,19 @@ + (void)lt_addLogger:(id <DDLogger>)logger
671 715 {
672 716 #if GCD_MAYBE_AVAILABLE
673 717
674   - // Add to linked list of LoggerNode elements.
  718 + // Add to loggers array.
675 719 // Need to create loggerQueue if loggerNode doesn't provide one.
676 720
677   - LoggerNode *loggerNode = malloc(sizeof(LoggerNode));
678   - loggerNode->logger = [logger retain];
  721 + dispatch_queue_t loggerQueue = NULL;
679 722
680 723 if ([logger respondsToSelector:@selector(loggerQueue)])
681 724 {
682 725 // Logger may be providing its own queue
683 726
684   - loggerNode->loggerQueue = [logger loggerQueue];
  727 + loggerQueue = [logger loggerQueue];
685 728 }
686 729
687   - if (loggerNode->loggerQueue)
688   - {
689   - dispatch_retain(loggerNode->loggerQueue);
690   - }
691   - else
  730 + if (loggerQueue == nil)
692 731 {
693 732 // Automatically create queue for the logger.
694 733 // Use the logger name as the queue name if possible.
@@ -699,11 +738,22 @@ + (void)lt_addLogger:(id <DDLogger>)logger
699 738 loggerQueueName = [[logger loggerName] UTF8String];
700 739 }
701 740
702   - loggerNode->loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
  741 + loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
703 742 }
704 743
705   - loggerNode->next = loggerNodes;
706   - loggerNodes = loggerNode;
  744 + DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue];
  745 + [loggers addObject:loggerNode];
  746 +
  747 + if ([logger respondsToSelector:@selector(didAddLogger)])
  748 + {
  749 + dispatch_async(loggerNode->loggerQueue, ^{
  750 + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  751 +
  752 + [logger didAddLogger];
  753 +
  754 + [pool drain];
  755 + });
  756 + }
707 757
708 758 #endif
709 759 }
@@ -715,13 +765,13 @@ + (void)lt_addLogger:(id <DDLogger>)logger
715 765
716 766 [loggers addObject:logger];
717 767
  768 + if ([logger respondsToSelector:@selector(didAddLogger)])
  769 + {
  770 + [logger didAddLogger];
  771 + }
  772 +
718 773 #endif
719 774 }
720   -
721   - if ([logger respondsToSelector:@selector(didAddLogger)])
722   - {
723   - [logger didAddLogger];
724   - }
725 775 }
726 776
727 777 /**
@@ -729,63 +779,59 @@ + (void)lt_addLogger:(id <DDLogger>)logger
729 779 **/
730 780 + (void)lt_removeLogger:(id <DDLogger>)logger
731 781 {
732   - if ([logger respondsToSelector:@selector(willRemoveLogger)])
733   - {
734   - [logger willRemoveLogger];
735   - }
736   -
737 782 if (IS_GCD_AVAILABLE)
738 783 {
739 784 #if GCD_MAYBE_AVAILABLE
740 785
741   - // Remove from linked list of LoggerNode elements.
742   - //
743   - // Need to release:
744   - // - logger
745   - // - loggerQueue
746   - // - loggerNode
  786 + // Find associated loggerNode in list of added loggers
747 787
748   - LoggerNode *prevNode = NULL;
749   - LoggerNode *currentNode = loggerNodes;
  788 + DDLoggerNode *loggerNode = nil;
750 789
751   - while (currentNode)
  790 + for (DDLoggerNode *node in loggers)
752 791 {
753   - if (currentNode->logger == logger)
  792 + if (node->logger == logger)
754 793 {
755   - if (prevNode)
756   - {
757   - // LoggerNode had previous node pointing to it.
758   - prevNode->next = currentNode->next;
759   - }
760   - else
761   - {
762   - // LoggerNode was first in list. Update loggerNodes pointer.
763   - loggerNodes = currentNode->next;
764   - }
765   -
766   - [currentNode->logger release];
767   - currentNode->logger = nil;
768   -
769   - dispatch_release(currentNode->loggerQueue);
770   - currentNode->loggerQueue = NULL;
771   -
772   - currentNode->next = NULL;
773   -
774   - free(currentNode);
775   -
  794 + loggerNode = node;
776 795 break;
777 796 }
778   -
779   - prevNode = currentNode;
780   - currentNode = currentNode->next;
781 797 }
782 798
  799 + if (loggerNode == nil)
  800 + {
  801 + NSLogDebug(@"DDLog: Request to remove logger which wasn't added");
  802 + return;
  803 + }
  804 +
  805 + // Notify logger
  806 +
  807 + if ([logger respondsToSelector:@selector(willRemoveLogger)])
  808 + {
  809 + dispatch_async(loggerNode->loggerQueue, ^{
  810 + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  811 +
  812 + [logger willRemoveLogger];
  813 +
  814 + [pool drain];
  815 + });
  816 + }
  817 +
  818 + // Remove from loggers array
  819 +
  820 + [loggers removeObject:loggerNode];
  821 +
783 822 #endif
784 823 }
785 824 else
786 825 {
787 826 #if GCD_MAYBE_UNAVAILABLE
788   -
  827 +
  828 + // Notify logger
  829 +
  830 + if ([logger respondsToSelector:@selector(willRemoveLogger)])
  831 + {
  832 + [logger willRemoveLogger];
  833 + }
  834 +
789 835 // Remove from loggers array
790 836
791 837 [loggers removeObject:logger];
@@ -799,54 +845,32 @@ + (void)lt_removeLogger:(id <DDLogger>)logger
799 845 **/
800 846 + (void)lt_removeAllLoggers
801 847 {
  848 + // Notify all loggers
  849 +
802 850 if (IS_GCD_AVAILABLE)
803 851 {
804 852 #if GCD_MAYBE_AVAILABLE
805 853
806   - // Iterate through linked list of LoggerNode elements.
807   - // For each one, notify the logger, and deallocate all associated resources.
808   - //
809   - // Need to release:
810   - // - logger
811   - // - loggerQueue
812   - // - loggerNode
813   -
814   - LoggerNode *nextNode;
815   - LoggerNode *currentNode = loggerNodes;
816   -
817   - while (currentNode)
  854 + for (DDLoggerNode *loggerNode in loggers)
818 855 {
819   - if ([currentNode->logger respondsToSelector:@selector(willRemoveLogger)])
  856 + if ([loggerNode->logger respondsToSelector:@selector(willRemoveLogger)])
820 857 {
821   - [currentNode->logger willRemoveLogger];
  858 + dispatch_async(loggerNode->loggerQueue, ^{
  859 + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  860 +
  861 + [loggerNode->logger willRemoveLogger];
  862 +
  863 + [pool drain];
  864 + });
822 865 }
823   -
824   - nextNode = currentNode->next;
825   -
826   - [currentNode->logger release];
827   - currentNode->logger = nil;
828   -
829   - dispatch_release(currentNode->loggerQueue);
830   - currentNode->loggerQueue = NULL;
831   -
832   - currentNode->next = NULL;
833   -
834   - free(currentNode);
835   -
836   - currentNode = nextNode;
837 866 }
838 867
839   - loggerNodes = NULL;
840   -
841 868 #endif
842 869 }
843 870 else
844 871 {
845 872 #if GCD_MAYBE_UNAVAILABLE
846 873
847   - // Notify all loggers.
848   - // And then remove them all from loggers array.
849   -
850 874 for (id <DDLogger> logger in loggers)
851 875 {
852 876 if ([logger respondsToSelector:@selector(willRemoveLogger)])
@@ -855,10 +879,12 @@ + (void)lt_removeAllLoggers
855 879 }
856 880 }
857 881
858   - [loggers removeAllObjects];
859   -
860 882 #endif
861 883 }
  884 +
  885 + // Remove all loggers from array
  886 +
  887 + [loggers removeAllObjects];
862 888 }
863 889
864 890 /**
@@ -881,21 +907,16 @@ + (void)lt_log:(DDLogMessage *)logMessage
881 907 // The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages.
882 908 // This would defeat the purpose of the efforts we made earlier to restrict the max queue size.
883 909
884   - LoggerNode *currentNode = loggerNodes;
885   -
886   - while (currentNode)
  910 + for (DDLoggerNode *loggerNode in loggers)
887 911 {
888   - dispatch_block_t loggerBlock = ^{
  912 + dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{
  913 +
889 914 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
890 915
891   - [currentNode->logger logMessage:logMessage];
  916 + [loggerNode->logger logMessage:logMessage];
892 917
893 918 [pool drain];
894   - };
895   -
896   - dispatch_group_async(loggingGroup, currentNode->loggerQueue, loggerBlock);
897   -
898   - currentNode = currentNode->next;
  919 + });
899 920 }
900 921
901 922 dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
@@ -904,21 +925,15 @@ + (void)lt_log:(DDLogMessage *)logMessage
904 925 {
905 926 // Execute each logger serialy, each within its own queue.
906 927
907   - LoggerNode *currentNode = loggerNodes;
908   -
909   - while (currentNode)
  928 + for (DDLoggerNode *loggerNode in loggers)
910 929 {
911   - dispatch_block_t loggerBlock = ^{
  930 + dispatch_sync(loggerNode->loggerQueue, ^{
912 931 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
913 932
914   - [currentNode->logger logMessage:logMessage];
  933 + [loggerNode->logger logMessage:logMessage];
915 934
916 935 [pool drain];
917   - };
918   -
919   - dispatch_sync(currentNode->loggerQueue, loggerBlock);
920   -
921   - currentNode = currentNode->next;
  936 + });
922 937 }
923 938 }
924 939
@@ -1015,23 +1030,19 @@ + (void)lt_flush
1015 1030 {
1016 1031 #if GCD_MAYBE_AVAILABLE
1017 1032
1018   - LoggerNode *currentNode = loggerNodes;
1019   -
1020   - while (currentNode)
  1033 + for (DDLoggerNode *loggerNode in loggers)
1021 1034 {
1022   - if ([currentNode->logger respondsToSelector:@selector(flush)])
  1035 + if ([loggerNode->logger respondsToSelector:@selector(flush)])
1023 1036 {
1024   - dispatch_block_t loggerBlock = ^{
  1037 + dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{
  1038 +
1025 1039 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1026 1040
1027   - [currentNode->logger flush];
  1041 + [loggerNode->logger flush];
1028 1042
1029 1043 [pool drain];
1030   - };
1031   -
1032   - dispatch_group_async(loggingGroup, currentNode->loggerQueue, loggerBlock);
  1044 + });
1033 1045 }
1034   - currentNode = currentNode->next;
1035 1046 }
1036 1047
1037 1048 dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
@@ -1136,6 +1147,46 @@ + (void)lt_flush
1136 1147 #pragma mark -
1137 1148 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1138 1149
  1150 +#if GCD_MAYBE_AVAILABLE
  1151 +
  1152 +@implementation DDLoggerNode
  1153 +
  1154 +- (id)initWithLogger:(id <DDLogger>)aLogger loggerQueue:(dispatch_queue_t)aLoggerQueue
  1155 +{
  1156 + if ((self = [super init]))
  1157 + {
  1158 + logger = [aLogger retain];
  1159 +
  1160 + if (aLoggerQueue) {
  1161 + loggerQueue = aLoggerQueue;
  1162 + dispatch_retain(loggerQueue);
  1163 + }
  1164 + }
  1165 + return self;
  1166 +}
  1167 +
  1168 ++ (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue
  1169 +{
  1170 + return [[[DDLoggerNode alloc] initWithLogger:logger loggerQueue:loggerQueue] autorelease];
  1171 +}
  1172 +
  1173 +- (void)dealloc
  1174 +{
  1175 + [logger release];
  1176 + if (loggerQueue) {
  1177 + dispatch_release(loggerQueue);
  1178 + }
  1179 + [super dealloc];
  1180 +}
  1181 +
  1182 +@end
  1183 +
  1184 +#endif
  1185 +
  1186 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1187 +#pragma mark -
  1188 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1189 +
1139 1190 @implementation DDLogMessage
1140 1191
1141 1192 - (id)initWithLogMsg:(NSString *)msg
@@ -1159,6 +1210,19 @@ - (id)initWithLogMsg:(NSString *)msg
1159 1210 timestamp = [[NSDate alloc] init];
1160 1211
1161 1212 machThreadID = pthread_mach_thread_np(pthread_self());
  1213 +
  1214 + if (IS_GCD_AVAILABLE)
  1215 + {
  1216 +#if GCD_MAYBE_AVAILABLE
  1217 + const char *label = dispatch_queue_get_label(dispatch_get_current_queue());
  1218 + if (label) {
  1219 + size_t labelLength = strlen(label);
  1220 + queueLabel = malloc(labelLength+1);
  1221 + strncpy(queueLabel, label, labelLength);
  1222 + queueLabel[labelLength] = 0;
  1223 + }
  1224 +#endif
  1225 + }
1162 1226 }
1163 1227 return self;
1164 1228 }
@@ -1201,6 +1265,14 @@ - (void)dealloc
1201 1265 [threadID release];
1202 1266 [fileName release];
1203 1267 [methodName release];
  1268 +
  1269 + if (IS_GCD_AVAILABLE) {
  1270 +#if GCD_MAYBE_AVAILABLE
  1271 + if (queueLabel != NULL) {
  1272 + free(queueLabel);
  1273 + }
  1274 +#endif
  1275 + }
1204 1276
1205 1277 [super dealloc];
1206 1278 }

0 comments on commit ce1b089

Please sign in to comment.
Something went wrong with that request. Please try again.