00001 /* Part of the culibs project, <http://www.eideticdew.org/culibs/>. 00002 * Copyright (C) 2007 Petter Urkedal <urkedal@nbi.dk> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef CU_WEAKPTR_H 00019 #define CU_WEAKPTR_H 00020 00021 #include <cu/memory.h> 00022 00023 CU_BEGIN_DECLARATIONS 00024 00025 void *cuP_weakptr_get_locked(void *link); 00026 00027 /** \defgroup cu_weakptr_h cu/weakptr.h: Weak Pointers 00028 ** @{ \ingroup cu_util_mod */ 00029 00030 /** True iff \a link holds the \c NULL pointer. */ 00031 CU_SINLINE cu_bool_t 00032 cu_weakptr_is_null(cu_hidden_ptr_t *link) 00033 { 00034 return *link != NULL; 00035 } 00036 00037 /** Safely return the value of the weak pointer \a link, or \c NULL if the 00038 ** object it pointed to was recycled. */ 00039 CU_SINLINE void * 00040 cu_weakptr_get(cu_hidden_ptr_t *link) 00041 { 00042 if (*link) 00043 return GC_call_with_alloc_lock(cuP_weakptr_get_locked, link); 00044 else 00045 return NULL; 00046 } 00047 00048 /** Construct \a link as a weak pointer with a NULL value. */ 00049 CU_SINLINE void 00050 cu_weakptr_init_null(cu_hidden_ptr_t *link) 00051 { 00052 *link = 0; 00053 } 00054 00055 /** Construct \a link as a weak pointer to \a ptr. If \a ptr gets collected, 00056 ** the link will be cleared, as manifested by a NULL return from \c 00057 ** cu_weakptr_get(link). 00058 ** \pre \a ptr != \c NULL */ 00059 CU_SINLINE void 00060 cu_weakptr_init(cu_hidden_ptr_t *link, void *ptr) 00061 { 00062 *link = cu_hide_ptr(ptr); 00063 GC_general_register_disappearing_link((void **)link, ptr); 00064 } 00065 00066 /** Release any disappearing link registration for \a link. */ 00067 CU_SINLINE void 00068 cu_weakptr_deinit(cu_hidden_ptr_t *link) 00069 { 00070 if ((uintptr_t)*link) 00071 GC_unregister_disappearing_link((void **)link); 00072 } 00073 00074 /** Assign \c NULL to \a link, releasing any previous disappearing link 00075 ** registration. */ 00076 CU_SINLINE void 00077 cu_weakptr_assign_null(cu_hidden_ptr_t *link) 00078 { 00079 cu_weakptr_deinit(link); 00080 cu_weakptr_init_null(link); 00081 } 00082 00083 /** Assign a non-\c NULL value to \a link, re-registering the disappearing 00084 ** link. 00085 ** \pre \a ptr != \c NULL */ 00086 CU_SINLINE void 00087 cu_weakptr_assign(cu_hidden_ptr_t *link, void *obj) 00088 { 00089 cu_weakptr_deinit(link); 00090 cu_weakptr_init(link, obj); 00091 } 00092 00093 /** @} */ 00094 CU_END_DECLARATIONS 00095 00096 #endif