- More refcounting fixes that now sustain abuse from spider, key is to be careful when iterating over a list when our...

Original commit message from CVS:
- More refcounting fixes that now sustain abuse from spider, key is to be
careful when iterating over a list when our current pointer could be
removed.
This commit is contained in:
Wim Taymans 2003-02-27 23:07:30 +00:00
parent e44d5c1d4a
commit 71775c37e3

View file

@ -165,9 +165,12 @@ struct _GstOptSchedulerGroup {
}; };
/* some group operations */ /* some group operations */
static GstOptSchedulerGroup* ref_group (GstOptSchedulerGroup *group); static GstOptSchedulerGroup* ref_group (GstOptSchedulerGroup *group);
static GstOptSchedulerGroup* unref_group (GstOptSchedulerGroup *group); #ifndef USE_COTHREADS
static void destroy_group (GstOptSchedulerGroup *group); static GstOptSchedulerGroup* ref_group_by_count (GstOptSchedulerGroup *group, gint count);
#endif
static GstOptSchedulerGroup* unref_group (GstOptSchedulerGroup *group);
static void destroy_group (GstOptSchedulerGroup *group);
/* /*
* Scheduler private data for an element * Scheduler private data for an element
@ -460,6 +463,9 @@ merge_chains (GstOptSchedulerChain *chain1, GstOptSchedulerChain *chain2)
GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) walk->data; GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) walk->data;
walk = g_slist_next (walk); walk = g_slist_next (walk);
GST_INFO (GST_CAT_SCHEDULING, "reparenting group %p from chain %p to %p",
group, chain2, chain1);
group->chain = NULL; group->chain = NULL;
chain2->num_groups--; chain2->num_groups--;
chain2 = unref_chain (chain2); chain2 = unref_chain (chain2);
@ -468,7 +474,9 @@ merge_chains (GstOptSchedulerChain *chain1, GstOptSchedulerChain *chain2)
chain1->groups = g_slist_prepend (chain1->groups, group); chain1->groups = g_slist_prepend (chain1->groups, group);
chain1->num_groups++; chain1->num_groups++;
} }
chain2 = unref_chain (chain2); g_slist_free (chain2->groups);
chain2->groups = NULL;
unref_chain (chain2);
return chain1; return chain1;
} }
@ -524,6 +532,19 @@ ref_group (GstOptSchedulerGroup *group)
return group; return group;
} }
#ifndef USE_COTHREADS
static GstOptSchedulerGroup*
ref_group_by_count (GstOptSchedulerGroup *group, gint count)
{
GST_INFO (GST_CAT_SCHEDULING, "ref group %p %d->%d", group,
group->refcount, group->refcount+count);
group->refcount += count;
return group;
}
#endif
static GstOptSchedulerGroup* static GstOptSchedulerGroup*
unref_group (GstOptSchedulerGroup *group) unref_group (GstOptSchedulerGroup *group)
{ {
@ -744,18 +765,24 @@ gst_opt_scheduler_schedule_run_queue (GstOptScheduler *osched)
while (osched->runqueue) { while (osched->runqueue) {
GstOptSchedulerGroup *group; GstOptSchedulerGroup *group;
gboolean res;
group = (GstOptSchedulerGroup *) osched->runqueue->data; group = (GstOptSchedulerGroup *) osched->runqueue->data;
/* runqueue hols refcount to group */
osched->runqueue = g_list_remove (osched->runqueue, group); osched->runqueue = g_list_remove (osched->runqueue, group);
GST_INFO (GST_CAT_SCHEDULING, "scheduling %p", group); GST_INFO (GST_CAT_SCHEDULING, "scheduling %p", group);
if (!schedule_group (group)) { res = schedule_group (group);
if (!res) {
g_warning ("error scheduling group %p", group); g_warning ("error scheduling group %p", group);
group_error_handler (group); group_error_handler (group);
} }
else {
GST_INFO (GST_CAT_SCHEDULING, "done scheduling %p", group); GST_INFO (GST_CAT_SCHEDULING, "done scheduling %p", group);
}
unref_group (group);
} }
GST_INFO (GST_CAT_SCHEDULING, "run queue length after scheduling %d", g_list_length (osched->runqueue)); GST_INFO (GST_CAT_SCHEDULING, "run queue length after scheduling %d", g_list_length (osched->runqueue));
@ -777,20 +804,22 @@ schedule_chain (GstOptSchedulerChain *chain)
while (groups) { while (groups) {
GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data;
groups = g_slist_next (groups);
if (!GST_OPT_SCHEDULER_GROUP_IS_DISABLED (group)) { if (!GST_OPT_SCHEDULER_GROUP_IS_DISABLED (group)) {
ref_group (group);
GST_INFO (GST_CAT_SCHEDULING, "scheduling group %p in chain %p", GST_INFO (GST_CAT_SCHEDULING, "scheduling group %p in chain %p",
group, chain); group, chain);
ref_group (group);
#ifdef USE_COTHREADS #ifdef USE_COTHREADS
schedule_group (group); schedule_group (group);
#else #else
osched->recursion = 0; osched->recursion = 0;
osched->runqueue = g_list_append (osched->runqueue, group); if (!schedule_group (group)) {
gst_opt_scheduler_schedule_run_queue (osched); g_warning ("error scheduling group %p", group);
group_error_handler (group);
}
else {
GST_INFO (GST_CAT_SCHEDULING, "done scheduling %p", group);
}
#endif #endif
GST_INFO (GST_CAT_SCHEDULING, "done scheduling group %p in chain %p", GST_INFO (GST_CAT_SCHEDULING, "done scheduling group %p in chain %p",
@ -798,6 +827,8 @@ schedule_chain (GstOptSchedulerChain *chain)
unref_group (group); unref_group (group);
break; break;
} }
groups = g_slist_next (groups);
} }
} }
@ -906,6 +937,7 @@ gst_opt_scheduler_loop_wrapper (GstPad *sinkpad, GstBuffer *buffer)
#else #else
GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)) = g_list_append (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)), buffer); GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)) = g_list_append (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)), buffer);
if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) {
ref_group (group);
osched->runqueue = g_list_append (osched->runqueue, group); osched->runqueue = g_list_append (osched->runqueue, group);
} }
#endif #endif
@ -938,9 +970,11 @@ gst_opt_scheduler_get_wrapper (GstPad *srcpad)
schedule_group (group); schedule_group (group);
#else #else
if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) {
ref_group (group); ref_group_by_count (group, 2);
osched->runqueue = g_list_append (osched->runqueue, group); osched->runqueue = g_list_append (osched->runqueue, group);
GST_INFO (GST_CAT_SCHEDULING, "recursing into scheduler group %p", group);
gst_opt_scheduler_schedule_run_queue (osched); gst_opt_scheduler_schedule_run_queue (osched);
GST_INFO (GST_CAT_SCHEDULING, "return from recurse group %p", group);
group = unref_group (group); group = unref_group (group);
/* group is gone */ /* group is gone */
if (group == NULL) { if (group == NULL) {
@ -1709,8 +1743,8 @@ gst_opt_scheduler_iterate (GstScheduler *sched)
chains = osched->chains; chains = osched->chains;
while (chains) { while (chains) {
GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data; GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data;
chains = g_slist_next (chains);
ref_chain (chain);
/* if the chain is not disabled, schedule it */ /* if the chain is not disabled, schedule it */
if (!GST_OPT_SCHEDULER_CHAIN_IS_DISABLED (chain)) { if (!GST_OPT_SCHEDULER_CHAIN_IS_DISABLED (chain)) {
schedule_chain (chain); schedule_chain (chain);
@ -1722,6 +1756,11 @@ gst_opt_scheduler_iterate (GstScheduler *sched)
GST_INFO (GST_CAT_SCHEDULING, "scheduler %p is in error", sched); GST_INFO (GST_CAT_SCHEDULING, "scheduler %p is in error", sched);
break; break;
} }
GST_INFO (GST_CAT_SCHEDULING, "iterate scheduled %p", chain);
chains = g_slist_next (chains);
unref_chain (chain);
} }
/* at this point it's possible that the scheduler state is /* at this point it's possible that the scheduler state is