| 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 |