• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import threading
6
7from devil.utils import reraiser_thread
8from devil.utils import timeout_retry
9
10
11class WeakConstant(object):
12  """A thread-safe, lazily initialized object.
13
14  This does not support modification after initialization. The intended
15  constant nature of the object is not enforced, though, hence the "weak".
16  """
17
18  def __init__(self, initializer):
19    self._initialized = threading.Event()
20    self._initializer = initializer
21    self._lock = threading.Lock()
22    self._val = None
23
24  def read(self):
25    """Get the object, creating it if necessary."""
26    if self._initialized.is_set():
27      return self._val
28    with self._lock:
29      if not self._initialized.is_set():
30        # We initialize the value on a separate thread to protect
31        # from holding self._lock indefinitely in the event that
32        # self._initializer hangs.
33        initializer_thread = reraiser_thread.ReraiserThread(
34            self._initializer)
35        initializer_thread.start()
36        timeout_retry.WaitFor(
37            lambda: initializer_thread.join(1) or not initializer_thread.isAlive(),
38            wait_period=0)
39        self._val = initializer_thread.GetReturnValue()
40        self._initialized.set()
41
42    return self._val
43