Skip to content

Commit

Permalink
Thread-safe RTCInitFieldTrialDictionary (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroshihorie authored May 9, 2024
1 parent 5cc0748 commit 7cf1e43
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions sdk/objc/api/peerconnection/RTCFieldTrials.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,58 @@

#import "RTCFieldTrials.h"

#import <os/lock.h>
#include <memory>

#import "base/RTCLogging.h"

#include "system_wrappers/include/field_trial.h"

NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey = @"WebRTC-Audio-ABWENoTWCC";
NSString * const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised";
NSString * const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03";
NSString * const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile";
NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey =
NSString *const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised";
NSString *const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03";
NSString *const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile";
NSString *const kRTCFieldTrialMinimizeResamplingOnMobileKey =
@"WebRTC-Audio-MinimizeResamplingOnMobile";
NSString *const kRTCFieldTrialUseNWPathMonitor = @"WebRTC-Network-UseNWPathMonitor";
NSString * const kRTCFieldTrialEnabledValue = @"Enabled";
NSString *const kRTCFieldTrialEnabledValue = @"Enabled";

// InitFieldTrialsFromString stores the char*, so the char array must outlive
// the application.
static char *gFieldTrialInitString = nullptr;
static os_unfair_lock fieldTrialLock = OS_UNFAIR_LOCK_INIT;

void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials) {
if (!fieldTrials) {
RTCLogWarning(@"No fieldTrials provided.");
return;
}

// Assemble the keys and values into the field trial string.
// We don't perform any extra format checking. That should be done by the underlying WebRTC calls.
NSMutableString *fieldTrialInitString = [NSMutableString string];
for (NSString *key in fieldTrials) {
NSString *fieldTrialEntry = [NSString stringWithFormat:@"%@/%@/", key, fieldTrials[key]];
[fieldTrialInitString appendString:fieldTrialEntry];
}

size_t len = fieldTrialInitString.length + 1;

// Locking before modifying global variable
os_unfair_lock_lock(&fieldTrialLock);
if (gFieldTrialInitString != nullptr) {
delete[] gFieldTrialInitString;
gFieldTrialInitString = nullptr;
}

gFieldTrialInitString = new char[len];
if (![fieldTrialInitString getCString:gFieldTrialInitString
maxLength:len
encoding:NSUTF8StringEncoding]) {
bool success = [fieldTrialInitString getCString:gFieldTrialInitString
maxLength:len
encoding:NSUTF8StringEncoding];
if (!success) {
RTCLogError(@"Failed to convert field trial string.");
os_unfair_lock_unlock(&fieldTrialLock);
return;
}

webrtc::field_trial::InitFieldTrialsFromString(gFieldTrialInitString);
os_unfair_lock_unlock(&fieldTrialLock);
}

0 comments on commit 7cf1e43

Please sign in to comment.