The Chromium Chronicle #25: थ्रेड की सुरक्षा से जुड़े एनोटेशन

एपिसोड 25: एसएफ़ओ में विक्टर कोस्टन की पेशकश (अक्टूबर, 2021)
पिछले एपिसोड

C++ में, डेटा के रेस होने की संभावना को समझते हुए, डेटा के हर सदस्य के ऐक्सेस के लिए एक छोटा सा थ्रेड-सुरक्षा सटीक होने के सबूत के तौर पर देखा जा सकता है. इन सबूतों से लोगों को बहुत दिमागी परेशानी होती है. खास तौर पर, जब कोड की समीक्षा की जा रही हो या उसे रीफ़ैक्टर किया जा रहा हो. Clang का स्टैटिक विश्लेषण फ़्रेमवर्क, थ्रेड की सुरक्षा से जुड़े सबूतों की ज़िम्मेदारी संभाल लेता है.

असुरक्षित क्लास में GUARDED_BY_CONTEXT() को डेटा मेंबर के लिए जोड़ें

Chrome के ज़्यादातर क्लास में थ्रेड सुरक्षित नहीं होते और इनका इस्तेमाल एक क्रम में किया जाना चाहिए. डेटा के उन सभी सदस्यों के लिए एनोटेशन जोड़ें जो थ्रेड के ज़रिए सुरक्षित नहीं हैं. ग़ैर-ज़रूरी एनोटेशन सुरक्षित होते हैं. हालांकि, एनोटेशन के न होने से डेटा के गलत होने का खतरा रहता है.

#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, क्रम की जांच लागू करता है

डेटा सदस्यों की व्याख्या करने के बदले, Clang यह पक्का करता है कि डेटा को ऐक्सेस करने वाला कोई भी तरीका, ऐसा करने से पहले क्रम की सुरक्षा जांच करे. जब सिस्टम को रीफ़ैक्टरिंग में ट्रांसफ़र किया जाता है, Clang, GUARDED_BY_CONTEXT() एनोटेशन को लागू करना जारी रखता है.

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

म्यूटेक्स का इस्तेमाल करने वाली थ्रेड-सेफ़ क्लास के डेटा मेंबर के लिए, GUARDED_BY() जोड़ें

Chrome की कुछ क्लास में थ्रेड की सुरक्षा के लिए, लॉक का इस्तेमाल करना ज़रूरी है. ऐसे मामलों में, डेटा के उन सभी सदस्यों के बारे में व्याख्या करें जो थ्रेड-सुरक्षित नहीं हैं. हर एनोटेशन एक म्यूटेक्स के बारे में बताता है, जो डेटा सदस्य को ऐक्सेस करते समय होल्ड होना चाहिए.

#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, लॉक हासिल करने की प्रक्रिया को लागू करता है

इंतज़ार करें और कंपाइलर को यह पक्का करने दें कि हर base::AutoLock सही स्कोप वाला है. साथ ही, उस लॉक Acquire() और Release() कॉल को सही तरीके से जोड़ा गया हो.

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