Tizen 2.1 base
[sdk/emulator/qemu.git] / hw / yagl_sharegroup.c
1 #include "yagl_sharegroup.h"
2 #include "yagl_object.h"
3
4 struct yagl_sharegroup_reap_entry
5 {
6     QLIST_ENTRY(yagl_sharegroup_reap_entry) entry;
7
8     struct yagl_object *obj;
9 };
10
11 QLIST_HEAD(yagl_object_list, yagl_sharegroup_reap_entry);
12
13 static void yagl_sharegroup_reap_list_move(struct yagl_sharegroup *sg,
14                                            struct yagl_object_list *tmp)
15 {
16     struct yagl_sharegroup_reap_entry *reap_entry, *next;
17
18     QLIST_FOREACH_SAFE(reap_entry, &sg->reap_list, entry, next) {
19         QLIST_REMOVE(reap_entry, entry);
20         QLIST_INSERT_HEAD(tmp, reap_entry, entry);
21     }
22
23     assert(QLIST_EMPTY(&sg->reap_list));
24 }
25
26 static void yagl_sharegroup_release_objects(struct yagl_object_list *tmp)
27 {
28     struct yagl_sharegroup_reap_entry *reap_entry, *next;
29
30     QLIST_FOREACH_SAFE(reap_entry, tmp, entry, next) {
31         QLIST_REMOVE(reap_entry, entry);
32         yagl_object_release(reap_entry->obj);
33         g_free(reap_entry);
34     }
35
36     assert(QLIST_EMPTY(tmp));
37 }
38
39 static void yagl_sharegroup_destroy(struct yagl_ref *ref)
40 {
41     struct yagl_sharegroup *sg = (struct yagl_sharegroup*)ref;
42     struct yagl_sharegroup_reap_entry *reap_entry, *next_reap_entry;
43     int i;
44
45     QLIST_FOREACH_SAFE(reap_entry, &sg->reap_list, entry, next_reap_entry) {
46         QLIST_REMOVE(reap_entry, entry);
47         yagl_object_set_nodelete(reap_entry->obj);
48         yagl_object_release(reap_entry->obj);
49         g_free(reap_entry);
50     }
51
52     assert(QLIST_EMPTY(&sg->reap_list));
53
54     for (i = 0; i < YAGL_NUM_NAMESPACES; ++i) {
55         yagl_namespace_cleanup(&sg->namespaces[i]);
56     }
57
58     qemu_mutex_destroy(&sg->mutex);
59
60     yagl_ref_cleanup(&sg->ref);
61
62     g_free(sg);
63 }
64
65 struct yagl_sharegroup *yagl_sharegroup_create(void)
66 {
67     struct yagl_sharegroup *sg = g_malloc0(sizeof(struct yagl_sharegroup));
68     int i;
69
70     yagl_ref_init(&sg->ref, &yagl_sharegroup_destroy);
71
72     qemu_mutex_init(&sg->mutex);
73
74     for (i = 0; i < YAGL_NUM_NAMESPACES; ++i) {
75         yagl_namespace_init(&sg->namespaces[i]);
76     }
77
78     QLIST_INIT(&sg->reap_list);
79
80     return sg;
81 }
82
83 void yagl_sharegroup_acquire(struct yagl_sharegroup *sg)
84 {
85     if (sg) {
86         yagl_ref_acquire(&sg->ref);
87     }
88 }
89
90 void yagl_sharegroup_release(struct yagl_sharegroup *sg)
91 {
92     if (sg) {
93         yagl_ref_release(&sg->ref);
94     }
95 }
96
97 yagl_object_name yagl_sharegroup_add(struct yagl_sharegroup *sg,
98                                      int ns,
99                                      struct yagl_object *obj)
100 {
101     struct yagl_object_list tmp;
102     yagl_object_name local_name;
103
104     QLIST_INIT(&tmp);
105
106     qemu_mutex_lock(&sg->mutex);
107
108     yagl_sharegroup_reap_list_move(sg, &tmp);
109
110     local_name = yagl_namespace_add(&sg->namespaces[ns], obj);
111
112     qemu_mutex_unlock(&sg->mutex);
113
114     yagl_sharegroup_release_objects(&tmp);
115
116     return local_name;
117 }
118
119 struct yagl_object *yagl_sharegroup_add_named(struct yagl_sharegroup *sg,
120                                               int ns,
121                                               yagl_object_name local_name,
122                                               struct yagl_object *obj)
123 {
124     struct yagl_object_list tmp;
125     struct yagl_object *ret;
126
127     QLIST_INIT(&tmp);
128
129     qemu_mutex_lock(&sg->mutex);
130
131     yagl_sharegroup_reap_list_move(sg, &tmp);
132
133     ret = yagl_namespace_add_named(&sg->namespaces[ns], local_name, obj);
134
135     qemu_mutex_unlock(&sg->mutex);
136
137     yagl_sharegroup_release_objects(&tmp);
138
139     return ret;
140 }
141
142 void yagl_sharegroup_remove(struct yagl_sharegroup *sg,
143                             int ns,
144                             yagl_object_name local_name)
145 {
146     struct yagl_object_list tmp;
147
148     QLIST_INIT(&tmp);
149
150     qemu_mutex_lock(&sg->mutex);
151
152     yagl_sharegroup_reap_list_move(sg, &tmp);
153
154     yagl_namespace_remove(&sg->namespaces[ns], local_name);
155
156     qemu_mutex_unlock(&sg->mutex);
157
158     yagl_sharegroup_release_objects(&tmp);
159 }
160
161 struct yagl_object *yagl_sharegroup_acquire_object(struct yagl_sharegroup *sg,
162                                                    int ns,
163                                                    yagl_object_name local_name)
164 {
165     struct yagl_object_list tmp;
166     struct yagl_object *obj;
167
168     QLIST_INIT(&tmp);
169
170     qemu_mutex_lock(&sg->mutex);
171
172     yagl_sharegroup_reap_list_move(sg, &tmp);
173
174     obj = yagl_namespace_acquire(&sg->namespaces[ns], local_name);
175
176     qemu_mutex_unlock(&sg->mutex);
177
178     yagl_sharegroup_release_objects(&tmp);
179
180     return obj;
181 }
182
183 void yagl_sharegroup_reap_object(struct yagl_sharegroup *sg,
184                                  struct yagl_object *obj)
185 {
186     struct yagl_sharegroup_reap_entry *reap_entry;
187
188     reap_entry = g_malloc0(sizeof(*reap_entry));
189
190     reap_entry->obj = obj;
191
192     qemu_mutex_lock(&sg->mutex);
193
194     QLIST_INSERT_HEAD(&sg->reap_list, reap_entry, entry);
195
196     qemu_mutex_unlock(&sg->mutex);
197 }