# Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import threading from devil.utils import reraiser_thread from devil.utils import timeout_retry class WeakConstant(object): """A thread-safe, lazily initialized object. This does not support modification after initialization. The intended constant nature of the object is not enforced, though, hence the "weak". """ def __init__(self, initializer): self._initialized = threading.Event() self._initializer = initializer self._lock = threading.Lock() self._val = None def read(self): """Get the object, creating it if necessary.""" if self._initialized.is_set(): return self._val with self._lock: if not self._initialized.is_set(): # We initialize the value on a separate thread to protect # from holding self._lock indefinitely in the event that # self._initializer hangs. initializer_thread = reraiser_thread.ReraiserThread(self._initializer) initializer_thread.start() timeout_retry.WaitFor( lambda: initializer_thread.join(1) or not initializer_thread. isAlive(), wait_period=0) self._val = initializer_thread.GetReturnValue() self._initialized.set() return self._val