ADD: added new version of protobuf

This commit is contained in:
Henry Winkel
2022-12-20 10:09:28 +01:00
parent 4a79559129
commit 1e2b3dda7b
1513 changed files with 123720 additions and 83381 deletions

View File

@@ -31,7 +31,6 @@
#import "GPBRootObject_PackagePrivate.h"
#import <objc/runtime.h>
#import <os/lock.h>
#import <CoreFoundation/CoreFoundation.h>
@@ -74,19 +73,26 @@ static uint32_t jenkins_one_at_a_time_hash(const char *key) {
// to worry about deallocation. All of the items are added to it at
// startup, and so the keys don't need to be retained/released.
// Keys are NULL terminated char *.
static const void *GPBRootExtensionKeyRetain(__unused CFAllocatorRef allocator, const void *value) {
static const void *GPBRootExtensionKeyRetain(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
return value;
}
static void GPBRootExtensionKeyRelease(__unused CFAllocatorRef allocator,
__unused const void *value) {}
static void GPBRootExtensionKeyRelease(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
#pragma unused(value)
}
static CFStringRef GPBRootExtensionCopyKeyDescription(const void *value) {
const char *key = (const char *)value;
return CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8);
return CFStringCreateWithCString(kCFAllocatorDefault, key,
kCFStringEncodingUTF8);
}
static Boolean GPBRootExtensionKeyEqual(const void *value1, const void *value2) {
static Boolean GPBRootExtensionKeyEqual(const void *value1,
const void *value2) {
const char *key1 = (const char *)value1;
const char *key2 = (const char *)value2;
return strcmp(key1, key2) == 0;
@@ -97,34 +103,31 @@ static CFHashCode GPBRootExtensionKeyHash(const void *value) {
return jenkins_one_at_a_time_hash(key);
}
// Long ago, this was an OSSpinLock, but then it came to light that there were issues for that on
// iOS:
// NOTE: OSSpinLock may seem like a good fit here but Apple engineers have
// pointed out that they are vulnerable to live locking on iOS in cases of
// priority inversion:
// http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
// https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
// It was changed to a dispatch_semaphore_t, but that has potential for priority inversion issues.
// The minOS versions are now high enough that os_unfair_lock can be used, and should provide
// all the support we need. For more information in the concurrency/locking space see:
// https://gist.github.com/tclementdev/6af616354912b0347cdf6db159c37057
// https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html
// https://developer.apple.com/videos/play/wwdc2017/706/
static os_unfair_lock gExtensionSingletonDictionaryLock = OS_UNFAIR_LOCK_INIT;
static dispatch_semaphore_t gExtensionSingletonDictionarySemaphore;
static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
static GPBExtensionRegistry *gDefaultExtensionRegistry = NULL;
+ (void)initialize {
// Ensure the global is started up.
if (!gExtensionSingletonDictionary) {
gExtensionSingletonDictionarySemaphore = dispatch_semaphore_create(1);
CFDictionaryKeyCallBacks keyCallBacks = {
// See description above for reason for using custom dictionary.
0,
GPBRootExtensionKeyRetain,
GPBRootExtensionKeyRelease,
GPBRootExtensionCopyKeyDescription,
GPBRootExtensionKeyEqual,
GPBRootExtensionKeyHash,
// See description above for reason for using custom dictionary.
0,
GPBRootExtensionKeyRetain,
GPBRootExtensionKeyRelease,
GPBRootExtensionCopyKeyDescription,
GPBRootExtensionKeyEqual,
GPBRootExtensionKeyHash,
};
gExtensionSingletonDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
&kCFTypeDictionaryValueCallBacks);
gExtensionSingletonDictionary =
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
&kCFTypeDictionaryValueCallBacks);
gDefaultExtensionRegistry = [[GPBExtensionRegistry alloc] init];
}
@@ -144,9 +147,10 @@ static GPBExtensionRegistry *gDefaultExtensionRegistry = NULL;
+ (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field {
const char *key = [field singletonNameC];
os_unfair_lock_lock(&gExtensionSingletonDictionaryLock);
dispatch_semaphore_wait(gExtensionSingletonDictionarySemaphore,
DISPATCH_TIME_FOREVER);
CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
os_unfair_lock_unlock(&gExtensionSingletonDictionaryLock);
dispatch_semaphore_signal(gExtensionSingletonDictionarySemaphore);
}
static id ExtensionForName(id self, SEL _cmd) {
@@ -178,20 +182,21 @@ static id ExtensionForName(id self, SEL _cmd) {
key[classNameLen + 1 + selNameLen] = '\0';
// NOTE: Even though this method is called from another C function,
// gExtensionSingletonDictionaryLock and gExtensionSingletonDictionary
// gExtensionSingletonDictionarySemaphore and gExtensionSingletonDictionary
// will always be initialized. This is because this call flow is just to
// lookup the Extension, meaning the code is calling an Extension class
// message on a Message or Root class. This guarantees that the class was
// initialized and Message classes ensure their Root was also initialized.
NSAssert(gExtensionSingletonDictionary, @"Startup order broken!");
os_unfair_lock_lock(&gExtensionSingletonDictionaryLock);
dispatch_semaphore_wait(gExtensionSingletonDictionarySemaphore,
DISPATCH_TIME_FOREVER);
id extension = (id)CFDictionaryGetValue(gExtensionSingletonDictionary, key);
// We can't remove the key from the dictionary here (as an optimization),
// two threads could have gone into +resolveClassMethod: for the same method,
// and ended up here; there's no way to ensure both return YES without letting
// both try to wire in the method.
os_unfair_lock_unlock(&gExtensionSingletonDictionaryLock);
dispatch_semaphore_signal(gExtensionSingletonDictionarySemaphore);
return extension;
}
@@ -207,9 +212,11 @@ BOOL GPBResolveExtensionClassMethod(Class self, SEL sel) {
// file.
id extension = ExtensionForName(self, sel);
if (extension != nil) {
const char *encoding = GPBMessageEncodingForSelector(@selector(getClassValue), NO);
const char *encoding =
GPBMessageEncodingForSelector(@selector(getClassValue), NO);
Class metaClass = objc_getMetaClass(class_getName(self));
IMP imp = imp_implementationWithBlock(^(__unused id obj) {
IMP imp = imp_implementationWithBlock(^(id obj) {
#pragma unused(obj)
return extension;
});
BOOL methodAdded = class_addMethod(metaClass, sel, imp, encoding);
@@ -227,6 +234,7 @@ BOOL GPBResolveExtensionClassMethod(Class self, SEL sel) {
return NO;
}
+ (BOOL)resolveClassMethod:(SEL)sel {
if (GPBResolveExtensionClassMethod(self, sel)) {
return YES;