Re: [g-a-devel]leaked objects - basic reference counting tutorial



Michael Meeks wrote:

On Mon, 2002-07-22 at 11:02, David Bolter wrote:

i get a whole bunch of leaked object output messages in the terminal which launched the gok.


	Ok; these are signs of gok not doing correct reference counting.

Okay, I wanted to be sure this was the cause - thanks!



leaked object gedit, role invalid


	So - someone took a ref on the gedit toplevel application object and
didn't release it.

	To release a reference you need to do:

	Accessible_unref (my_ref);

If my call to Accessible_unref reduces the ref count for that object to 0, is it immediately removed from the hash table?


	You have to take a reference if you want to keep a reference beyond the
lifetime of the callback you took it in [ if in a callback ], ie. this
is wrong:

Right, okay - just for events I may need to ref... (I think I was also added a ref for interrogated accessibles - tsk tsk).

Thanks again Michael, for the info, and the patch.

cheers,

~~David



static Accessible *acc = NULL;
void my_event_callback (AccessibleEvent *e)
{
	acc = e->source;		/* WRONG */
}

	Since as soon as the method quits acc will be left pointing at an
accessible that we don't own a reference on so, instead we must do:

void my_event_callback (AccessibleEvent *e)
{
	Accessible_unref (acc);
	acc = e->source;
	Accessible_ref (acc);           /* RIGHT */
}

	I think (owing to the miracle of rushed API design) that you can't do
the obvious:

	acc = Accessible_ref (e->source);

	which would be far superior.

	That's for callbacks; for methods:

AccessibleText *a = Accessible_getText (acc);

	returns a reference - indeed, any method that returns an Accessible,
returns a reference to it; thus you have to unref it later, or it is
leaked thus:

AccessibleText *a = Accessible_getText (acc);
... do something with it ...
Accessible_unref (a);

	Finally it would be best if the code actually told you how many refs
were leaked, otherwise it's going to be difficult to see you making any
progress eliminating them [ which can only really be done by code
reading ]: I'd add this patch:

	[ extraordinary to put brackets round a ? conditional expr ]

	
Index: spi_main.c
===================================================================
RCS file: /cvs/gnome/at-spi/cspi/spi_main.c,v
retrieving revision 1.26
diff -u -p -u -r1.26 spi_main.c
--- spi_main.c	20 Jun 2002 12:10:34 -0000	1.26
+++ spi_main.c	23 Jul 2002 15:00:57 -0000
@@ -378,9 +378,10 @@ report_leaked_ref (gpointer key, gpointe
	if (cspi_exception ()) name = NULL;
	role = Accessible_getRoleName (a);
	if (cspi_exception ()) role = NULL;
-	fprintf (stderr, "leaked object %s, role %s\n", (name) ? name : "<?>",
-		 (role) ? role : "<?>");
-	if (name) SPI_freeString (name);
+	fprintf (stderr, "leaked %d references to object %s, role %s\n",
+		 a->ref_count, name ? name : "<?>", role ? role : "<?>");
+	if (name)
+		SPI_freeString (name);
}

	Finally - leaks are worth fixing, since otherwise the app at the other
end will eventually run out of resources, which you are keeping alive by
holding references to - perhaps to objects that no-longer have peers
that exist.

	Bill - can I commit the above [ and fix a warning in cspi/bonobo that's
annoying me ? ]

	Regards,

		Michael.







[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]