| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2023 Google LLC. All rights reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file or at | |
| // https://developers.google.com/open-source/licenses/bsd | |
| #include "python/free_threading/lazy_ptr.h" | |
| // Must be last. | |
| #include "upb/port/def.inc" | |
| #ifdef Py_GIL_DISABLED | |
| void* PyUpb_LazyPtr_LazyInit(void* lazy_ptr, PyUpb_PtrInitFunc init_fn, | |
| PyUpb_PtrFreeFunc free_fn, void* ctx) { | |
| UPB_ATOMIC(void*)* atomic_ptr = (UPB_ATOMIC(void*)*)lazy_ptr; | |
| void* ptr = upb_Atomic_Load(atomic_ptr, memory_order_acquire); | |
| if (ptr) return ptr; | |
| void* new_ptr = init_fn(ctx); | |
| if (!new_ptr) return NULL; | |
| void* expected = NULL; | |
| if (!upb_Atomic_CompareExchangeStrong(atomic_ptr, &expected, new_ptr, | |
| memory_order_release, | |
| memory_order_acquire)) { | |
| if (free_fn) free_fn(new_ptr); | |
| return expected; | |
| } | |
| return new_ptr; | |
| } | |
| #endif |