randr: Make deletion of output properties more robust

Previously there was two branches of code with small discrepancies between them
(especially prop->valid_values field was not free(3)ed). Extract the common
routine and fix double-free prop->valid_values in RRDestroyOutputProperty by
the way.

Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net>
Reviewed-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
Mikhail Gusarov 2010-06-06 20:37:07 +07:00
parent 0a4d8cbdcd
commit 67b824a81b

View File

@ -53,25 +53,39 @@ static void RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
WalkTree(pScreen, DeliverPropertyEvent, event);
}
static void
RRDestroyOutputProperty (RRPropertyPtr prop)
{
free(prop->valid_values);
free(prop->current.data);
free(prop->pending.data);
free(prop);
}
static void
RRDeleteProperty(RROutputRec *output, RRPropertyRec *prop)
{
xRROutputPropertyNotifyEvent event;
event.type = RREventBase + RRNotify;
event.subCode = RRNotify_OutputProperty;
event.output = output->id;
event.state = PropertyDelete;
event.atom = prop->propertyName;
event.timestamp = currentTime.milliseconds;
RRDeliverPropertyEvent(output->pScreen, (xEvent *)&event);
RRDestroyOutputProperty(prop);
}
void
RRDeleteAllOutputProperties (RROutputPtr output)
RRDeleteAllOutputProperties(RROutputPtr output)
{
RRPropertyPtr prop, next;
xRROutputPropertyNotifyEvent event;
for (prop = output->properties; prop; prop = next)
{
for (prop = output->properties; prop; prop = next) {
next = prop->next;
event.type = RREventBase + RRNotify;
event.subCode = RRNotify_OutputProperty;
event.output = output->id;
event.state = PropertyDelete;
event.atom = prop->propertyName;
event.timestamp = currentTime.milliseconds;
RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event);
free(prop->current.data);
free(prop->pending.data);
free(prop);
RRDeleteProperty(output, prop);
}
}
@ -104,37 +118,17 @@ RRCreateOutputProperty (Atom property)
return prop;
}
static void
RRDestroyOutputProperty (RRPropertyPtr prop)
{
free(prop->valid_values);
free(prop->current.data);
free(prop->pending.data);
free(prop->valid_values);
free(prop);
}
void
RRDeleteOutputProperty (RROutputPtr output, Atom property)
RRDeleteOutputProperty(RROutputPtr output, Atom property)
{
RRPropertyPtr prop, *prev;
xRROutputPropertyNotifyEvent event;
RRPropertyRec *prop, **prev;
for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
if (prop->propertyName == property)
break;
if (prop)
{
*prev = prop->next;
event.type = RREventBase + RRNotify;
event.subCode = RRNotify_OutputProperty;
event.output = output->id;
event.state = PropertyDelete;
event.atom = prop->propertyName;
event.timestamp = currentTime.milliseconds;
RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event);
RRDestroyOutputProperty (prop);
}
if (prop->propertyName == property) {
*prev = prop->next;
RRDeleteProperty(output, prop);
return;
}
}
int