Chromium Chronicle #25: İş Parçacığı Güvenliğiyle İlgili Ek Açıklamalar

Episode 25: SFO'da Victor Costan tarafından (Ekim 2021)
Önceki bölümler

C++'ta veri yarışları olasılığını ortadan kaldırmak, her veri üyesinin erişimi için küçük bir iş parçacığı güvenliği kanıtı anlamına gelir. Bu kanıtlar özellikle kodları gözden geçirirken ya da yeniden düzenlerken zihinsel anlamda çok fazla sıkıntıya yol açar. Clang'ın statik analiz çerçevesi, iş parçacığı güvenliği kanıtlarının zahmetini üstlenir.

GUARDED_BY_CONTEXT() öğesini, ileti dizisi açısından güvenli olmayan sınıflardaki veri üyelerine ekleyin

Çoğu Chrome sınıfı iş parçacığı açısından güvenli değildir ve tek bir sırada kullanılmalıdır. İleti dizisi açısından güvenli olmayan tüm veri üyelerine ek açıklama ekleyin. Gereksiz ek açıklamalar güvenlidir ancak eksik ek açıklamalar veri yarışı riski taşır.

#include "base/sequence_checker.h"  // for SEQUENCE_CHECKER()
#include "base/thread_annotations.h"  // for GUARDED_BY_CONTEXT()

class Cache {
  // Methods here.
 private:
  SEQUENCE_CHECKER(sequence_checker_);
  base::flat_map<std::string, std::string> data_ GUARDED_BY_CONTEXT(sequence_checker_);
};

Clang, dizi kontrollerini zorunlu kılar

Clang, veri üyelerine ek açıklama eklemenin karşılığında verilere erişen tüm yöntemlerin, bunu yapmadan önce bir dizi güvenlik kontrolü gerçekleştirmesini sağlar. Kod yeniden düzenleme işlemlerinde hareket ettikçe Clang, GUARDED_BY_CONTEXT() ek açıklamasını uygulamaya devam eder.

void Cache::Set(base::StringPiece key, base::StringPiece value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);  // Clang warns without this.
  data_.emplace(key, value);
}

Karşılıklı dışlama kullanan ileti dizisi güvenli sınıflardaki veri üyelerine GUARDED_BY() ekleyin

Chrome'daki bazı sınıflarda iş parçacığı güvenliği için kilit kullanılmalıdır. Bu durumlarda, ileti dizisi açısından güvenli olmayan tüm veri üyelerine ek açıklama ekleyin. Her ek açıklama, veri üyesine erişirken tutulması gereken bir karşılıklı dışlamaya işaret eder.

#include "base/thread_annotations.h"  // for GUARDED_BY()

class ThreadSafeCache {
  // Methods here.
  private:
    base::Lock lock_;
    base::flat_map<std::string, std::string> data_ GUARDED_BY(lock_);
};

Clang, kilit edinmeleri zorunlu kılıyor

Bekleyin ve derleyicinin her base::AutoLock kapsamının doğru olduğundan ve Acquire() ile Release() çağrılarının doğru şekilde eşlendiğinden emin olmasını sağlayın.

void ThreadSafeCache::Set(base::StringPiece key, base::StringPiece value) {
  base::AutoLock auto_lock(lock_);  // Clang warns without this.
  data_.emplace(key, value);
}