summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-11-11 14:38:17 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-11-11 14:57:52 +0900
commit80ebf5b4531384bebac4f4b851d3489b98f3eb99 (patch)
tree8e89550a9f2d33800e9e28bd37416e4079dcf190
parent8b1b8d5cf04f5e176cc4de6c04790e90eeac4ff2 (diff)
edje - signal match code - clean up function readablity and fix crash
this just clens up the _edje_signal_callback_push() to be simpler and less wordy with the same actual logic, just pointless things like return; at end of func removed, use tmp instead of gp->matches everywhere and not just in one section etc. also set hashed bool to eina true/false i as opposed to sometimes 0, sometimes eina true/false and also track it religiously as well as matches array when freed - hunting bug for whatever reason after these cleanups i can't reproduce a signal crash i had which seemed to find freed matches in the hash that should not have been there. (a hash find walking a bucket found freed memory for the match in the hash entry - should not have been though reading the code). @fix
-rw-r--r--src/lib/edje/edje_signal.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/src/lib/edje/edje_signal.c b/src/lib/edje/edje_signal.c
index ccefc7f85f..f77d47ec17 100644
--- a/src/lib/edje/edje_signal.c
+++ b/src/lib/edje/edje_signal.c
@@ -177,65 +177,63 @@ _edje_signal_callback_push(const Edje_Signal_Callback_Group *cgp,
177 Edje_Signal_Callback_Group *gp = (Edje_Signal_Callback_Group *)cgp; 177 Edje_Signal_Callback_Group *gp = (Edje_Signal_Callback_Group *)cgp;
178 unsigned int i; 178 unsigned int i;
179 Edje_Signal_Callback_Flags flags; 179 Edje_Signal_Callback_Flags flags;
180 Edje_Signal_Callback_Matches *tmp;
180 181
181 flags.delete_me = EINA_FALSE; 182 flags.delete_me = EINA_FALSE;
182 flags.just_added = EINA_TRUE; 183 flags.just_added = EINA_TRUE;
183 flags.propagate = !!propagate; 184 flags.propagate = !!propagate;
184 185
185 // let's first try to see if we do find an empty matching stop 186 tmp = (Edje_Signal_Callback_Matches *)gp->matches;
186 for (i = 0; i < gp->matches->matches_count; i++)
187 if (sig == gp->matches->matches[i].signal &&
188 src == gp->matches->matches[i].source &&
189 func == gp->matches->matches[i].func)
190 {
191 if (gp->flags[i].delete_me)
192 {
193 _edje_signal_callback_unset(gp, i);
194 _edje_signal_callback_set(gp, i, sig, src, func, data, flags);
195 return;
196 }
197 }
198 187
199 if (gp->matches->hashed) 188 // let's first try to see if we do find an empty matching stop
189 for (i = 0; i < tmp->matches_count; i++)
200 { 190 {
201 Edje_Signal_Callback_Matches *tmp; 191 if ((sig == tmp->matches[i].signal) &&
202 192 (src == tmp->matches[i].source) &&
203 tmp = (Edje_Signal_Callback_Matches *)gp->matches; 193 (func == tmp->matches[i].func) &&
194 (gp->flags[i].delete_me))
195 {
196 _edje_signal_callback_unset(gp, i);
197 _edje_signal_callback_set(gp, i, sig, src, func, data, flags);
198 return;
199 }
200 }
204 201
202 if (tmp->hashed)
203 {
205 if (EINA_REFCOUNT_GET(tmp) == 1) 204 if (EINA_REFCOUNT_GET(tmp) == 1)
206 { 205 {
207 eina_hash_del(signal_match, tmp, tmp); 206 eina_hash_del(signal_match, tmp, tmp);
208 tmp->hashed = 0; 207 tmp->hashed = EINA_FALSE;
209 } 208 }
210 else 209 else
211 { 210 {
212 Edje_Signal_Callback_Matches *tmp_dup; 211 Edje_Signal_Callback_Matches *tmp_dup =
213 tmp_dup = (Edje_Signal_Callback_Matches *)_edje_signal_callback_matches_dup(tmp); 212 (Edje_Signal_Callback_Matches *)
213 _edje_signal_callback_matches_dup(tmp);
214 if (!tmp_dup) return; 214 if (!tmp_dup) return;
215 EINA_REFCOUNT_UNREF(tmp) 215 EINA_REFCOUNT_UNREF(tmp)
216 (void) 0; // Nothing to do because the case where refcount == 1 was already handle above. 216 (void) 0; // do nothing because if refcount == 1 handle above.
217 gp->matches = tmp_dup; 217 gp->matches = tmp = tmp_dup;
218 } 218 }
219 219 assert(tmp->hashed == EINA_FALSE);
220 assert(gp->matches->hashed == 0);
221 } 220 }
222 221
223 // search an empty spot now 222 // search an empty spot now
224 for (i = 0; i < gp->matches->matches_count; i++) 223 for (i = 0; i < tmp->matches_count; i++)
225 if (gp->flags[i].delete_me) 224 {
226 { 225 if (gp->flags[i].delete_me)
227 _edje_signal_callback_unset(gp, i); 226 {
228 _edje_signal_callback_set(gp, i, sig, src, func, data, flags); 227 _edje_signal_callback_unset(gp, i);
229 return; 228 _edje_signal_callback_set(gp, i, sig, src, func, data, flags);
230 } 229 return;
230 }
231 }
231 232
232 _edje_signal_callback_grow(gp); 233 _edje_signal_callback_grow(gp);
233
234 // Set propagate and just_added flags 234 // Set propagate and just_added flags
235 _edje_signal_callback_set(gp, gp->matches->matches_count - 1, 235 _edje_signal_callback_set(gp, tmp->matches_count - 1,
236 sig, src, func, data, flags); 236 sig, src, func, data, flags);
237
238 return;
239} 237}
240 238
241const Edje_Signal_Callback_Group * 239const Edje_Signal_Callback_Group *
@@ -270,7 +268,10 @@ _edje_signal_callback_matches_unref(Edje_Signal_Callback_Matches *m)
270 _edje_signal_callback_patterns_unref(m->patterns); 268 _edje_signal_callback_patterns_unref(m->patterns);
271 269
272 if (m->hashed) 270 if (m->hashed)
273 eina_hash_del(signal_match, m, m); 271 {
272 eina_hash_del(signal_match, m, m);
273 m->hashed = EINA_FALSE;
274 }
274 275
275 for (i = 0; i < m->matches_count; ++i) 276 for (i = 0; i < m->matches_count; ++i)
276 { 277 {
@@ -278,6 +279,7 @@ _edje_signal_callback_matches_unref(Edje_Signal_Callback_Matches *m)
278 eina_stringshare_del(m->matches[i].source); 279 eina_stringshare_del(m->matches[i].source);
279 } 280 }
280 free(m->matches); 281 free(m->matches);
282 m->matches = NULL;
281 free(m); 283 free(m);
282 } 284 }
283} 285}