OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // http://code.google.com/p/protobuf/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 void SchedYield() { | 55 void SchedYield() { |
56 #ifdef _WIN32 | 56 #ifdef _WIN32 |
57 Sleep(0); | 57 Sleep(0); |
58 #else // POSIX | 58 #else // POSIX |
59 sched_yield(); | 59 sched_yield(); |
60 #endif | 60 #endif |
61 } | 61 } |
62 | 62 |
63 } // namespace | 63 } // namespace |
64 | 64 |
| 65 void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { |
| 66 if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { |
| 67 internal::FunctionClosure0 func(init_func, false); |
| 68 GoogleOnceInitImpl(once, &func); |
| 69 } |
| 70 } |
| 71 |
65 void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) { | 72 void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) { |
66 internal::AtomicWord state = internal::Acquire_Load(once); | 73 internal::AtomicWord state = internal::Acquire_Load(once); |
67 // Fast path. The provided closure was already executed. | 74 // Fast path. The provided closure was already executed. |
68 if (state == ONCE_STATE_DONE) { | 75 if (state == ONCE_STATE_DONE) { |
69 return; | 76 return; |
70 } | 77 } |
71 // The closure execution did not complete yet. The once object can be in one | 78 // The closure execution did not complete yet. The once object can be in one |
72 // of the two following states: | 79 // of the two following states: |
73 // - UNINITIALIZED: We are the first thread calling this function. | 80 // - UNINITIALIZED: We are the first thread calling this function. |
74 // - EXECUTING_CLOSURE: Another thread is already executing the closure. | 81 // - EXECUTING_CLOSURE: Another thread is already executing the closure. |
(...skipping 11 matching lines...) Expand all Loading... |
86 // Another thread has already started executing the closure. We need to | 93 // Another thread has already started executing the closure. We need to |
87 // wait until it completes the initialization. | 94 // wait until it completes the initialization. |
88 while (state == ONCE_STATE_EXECUTING_CLOSURE) { | 95 while (state == ONCE_STATE_EXECUTING_CLOSURE) { |
89 // Note that futex() could be used here on Linux as an improvement. | 96 // Note that futex() could be used here on Linux as an improvement. |
90 SchedYield(); | 97 SchedYield(); |
91 state = internal::Acquire_Load(once); | 98 state = internal::Acquire_Load(once); |
92 } | 99 } |
93 } | 100 } |
94 } | 101 } |
95 | 102 |
96 void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { | |
97 if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { | |
98 internal::FunctionClosure0 func(init_func, false); | |
99 GoogleOnceInitImpl(once, &func); | |
100 } | |
101 } | |
102 | |
103 } // namespace protobuf | 103 } // namespace protobuf |
104 } // namespace google | 104 } // namespace google |
105 | 105 |
106 #endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY | 106 #endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY |
OLD | NEW |