1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 2010 gEDA Contributors (see ChangeLog for details)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 #include "libgeda_priv.h"
25 * \brief Utility functions for weak references and pointers.
27 * \warning Do not write code which relies on the order in which weak
28 * reference callback functions are notified.
33 void (*notify_func
)(void *, void *);
37 /*! \brief Notify weak reference watchers that a structure is dead.
38 * \par Function Description
39 * For each entry in \a weak_refs, call notify function with the dead
40 * pointer \a dead_ptr and the entry's specified user data, and free
41 * \a weak_refs. Should be called during destruction of an structure
42 * that allows weak references.
44 * \param [in] dead_ptr Pointer to structure being destroyed.
45 * \param [in,out] weak_refs List of registered weak references.
48 s_weakref_notify (void *dead_ptr
, GList
*weak_refs
)
51 struct WeakRef
*entry
;
52 for (iter
= weak_refs
; iter
!= NULL
; iter
= g_list_next (iter
)) {
53 entry
= (struct WeakRef
*) iter
->data
;
54 if (entry
!= NULL
&& entry
->notify_func
!= NULL
) {
55 entry
->notify_func (dead_ptr
, entry
->user_data
);
59 g_list_free (weak_refs
);
62 /*! \brief Add a weak reference watcher to a weak ref list.
63 * \par Function Description
64 * Adds the weak reference callback \a notify_func to the weak
65 * reference list \a weak_refs, returning the new head of \a
66 * weak_refs. \a notify_func will be called with two arguments: a
67 * pointer to the object being destroyed, and the \a user_data.
69 * \param [in,out] weak_refs List of registered weak references.
70 * \param [in] notify_func Weak reference notify function.
71 * \param [in] user_data Data to be passed to \a notify_func.
73 * \return new head of \a weak_refs list.
76 s_weakref_add (GList
*weak_refs
, void (*notify_func
)(void *, void *),
79 struct WeakRef
*entry
= g_malloc0 (sizeof (struct WeakRef
));
80 entry
->notify_func
= notify_func
;
81 entry
->user_data
= user_data
;
82 return g_list_prepend (weak_refs
, entry
);
85 /*! \brief Remove a weak reference watcher from a weak ref list.
86 * \par Function Description
87 * Removes a weak reference callback from the weak reference list \a
88 * weak_refs, returning the new head of \a weak_refs.
90 * \param [in,out] weak_refs List of registered weak references.
91 * \param [in] notify_func Notify function to search for.
92 * \param [in] user_data User data to search for.
94 * \return new head of \a weak_refs list.
97 s_weakref_remove (GList
*weak_refs
, void (*notify_func
)(void *, void *),
101 struct WeakRef
*entry
;
102 for (iter
= weak_refs
; iter
!= NULL
; iter
= g_list_next (iter
)) {
104 if ((entry
!= NULL
) &&
105 (entry
->notify_func
== notify_func
) &&
106 (entry
->user_data
== user_data
)) {
111 return g_list_remove_all (weak_refs
, NULL
);
115 weak_ptr_notify_func (void *dead_ptr
, void *user_data
) {
116 void **weak_pointer_loc
= (void **) user_data
;
117 if (weak_pointer_loc
!= NULL
) {
118 *weak_pointer_loc
= NULL
;
122 /*! \brief Add a weak pointer to a weak ref list.
123 * \par Function Description
124 * Adds a weak reference for \a weak_pointer_loc to the weak reference
125 * list \a weak_refs, returning the new head of \a weak_refs.
127 * \param [in,out] weak_refs List of registered weak references.
128 * \param [in] weak_pointer_loc Memory address of a pointer.
130 * \return new head of \a weak_refs list.
133 s_weakref_add_ptr (GList
*weak_refs
, void **weak_pointer_loc
)
135 return s_weakref_add (weak_refs
, weak_ptr_notify_func
, weak_pointer_loc
);
138 /*! \brief Remove a weak pointer from a weak ref list.
139 * \par Function Description
140 * Removes the weak reference for \a weak_pointer_loc from the weak
141 * reference list \a weak_refs, returning the new head of \a
144 * \param [in,out] weak_refs List of registered weak references.
145 * \param [in] weak_pointer_loc Memory address of a pointer.
147 * \return new head of \a weak_refs list.
150 s_weakref_remove_ptr (GList
*weak_refs
, void **weak_pointer_loc
)
152 return s_weakref_remove (weak_refs
, weak_ptr_notify_func
, weak_pointer_loc
);