MCPcopy Create free account
hub / github.com/apache/brpc / bthread_once_impl

Function bthread_once_impl

src/bthread/bthread_once.cpp:32–71  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

30namespace bthread {
31
32int bthread_once_impl(bthread_once_t* once_control, void (*init_routine)()) {
33 butil::atomic<int>* butex = once_control->_butex;
34 // We need acquire memory order for this load because if the value
35 // signals that initialization has finished, we need to see any
36 // data modifications done during initialization.
37 int val = butex->load(butil::memory_order_acquire);
38 if (BAIDU_LIKELY(val == bthread_once_t::INITIALIZED)) {
39 // The initialization has already been done.
40 return 0;
41 }
42 val = bthread_once_t::UNINITIALIZED;
43 if (butex->compare_exchange_strong(val, bthread_once_t::INPROGRESS,
44 butil::memory_order_relaxed,
45 butil::memory_order_relaxed)) {
46 // This (b)thread is the first and the Only one here. Do the initialization.
47 init_routine();
48 // Mark *once_control as having finished the initialization. We need
49 // release memory order here because we need to synchronize with other
50 // (b)threads that want to use the initialized data.
51 butex->store(bthread_once_t::INITIALIZED, butil::memory_order_release);
52 // Wake up all other (b)threads.
53 bthread::butex_wake_all(butex);
54 return 0;
55 }
56
57 while (true) {
58 // Same as above, we need acquire memory order.
59 val = butex->load(butil::memory_order_acquire);
60 if (BAIDU_LIKELY(val == bthread_once_t::INITIALIZED)) {
61 // The initialization has already been done.
62 return 0;
63 }
64 // Unless your constructor can be very time consuming, it is very unlikely o hit
65 // this race. When it does, we just wait the thread until the object has been created.
66 if (bthread::butex_wait(butex, val, NULL) < 0 &&
67 errno != EWOULDBLOCK && errno != EINTR/*note*/) {
68 return errno;
69 }
70 }
71}
72
73} // namespace bthread
74

Callers 1

bthread_onceFunction · 0.85

Calls 6

init_routineFunction · 0.85
butex_wake_allFunction · 0.85
butex_waitFunction · 0.85
loadMethod · 0.45
storeMethod · 0.45

Tested by

no test coverage detected