Closed Bug 93217 Opened 23 years ago Closed 23 years ago

[review]nsRenderingContextMac doesn't reference count offscreens

Categories

(Core Graveyard :: GFX, defect, P2)

PowerPC
Mac System 9.x
defect

Tracking

(Not tracked)

RESOLVED FIXED
mozilla0.9.8

People

(Reporter: jmt, Assigned: pierre)

References

Details

Attachments

(2 files)

[kmclusk, I know you're not a Mac person, but in the absence of an explicit
owner for gfx/src/mac on the modules pages, I'm hoping you can CC someone who
is. dcone? sfraser?]

nsRenderingContextMac::CreateDrawingSurface doesn't NS_ADDREF the
nsDrawingSurfaceMac it creates; similarly ::DestroyDrawingSurface calls 'delete'
explicitly rather than using an NS_IF_RELASE.

This is causing instantaneous deletion of the drawing surface when the SVG code
I'm helping with passes the surface through getter_AddRefs and friends (since
the reference count is zero). Both nsRenderingContextWin and
nsRenderingContextGtk use add/release.

The fix below simply calls NS_ADDREF in Create, and replaces the delete in
::DestroyDrawingSurface with an NS_IF_RELEASE. I have been running with this
change in me tree for several days without any (apparent) issues.

Proposed patch:

Index: mozilla/gfx/src/mac/nsRenderingContextMac.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/mac/nsRenderingContextMac.cpp,v
retrieving revision 1.124
diff -u -2 -r1.124 nsRenderingContextMac.cpp
--- mozilla/gfx/src/mac/nsRenderingContextMac.cpp	2001/07/16 02:38:50	1.124
+++ mozilla/gfx/src/mac/nsRenderingContextMac.cpp	2001/08/01 11:08:19
@@ -506,4 +510,6 @@
 
	return NS_ERROR_OUT_OF_MEMORY;
 
+
NS_ADDREF(surface);
+
 	nsresult rv = surface->Init(depth, macRect.right, macRect.bottom, aSurfFlags);
 	if (NS_SUCCEEDED(rv))
@@ -537,6 +543,8 @@
 */
 	// delete the surface
-
delete surface;
-
+
 //release it...
+  	NS_IF_RELEASE(surface);
+  
 	return NS_OK;
 }
Over to dcone. Note that this blocks SVG work, so we need a fix.
Assignee: kmcclusk → dcone
Status: UNCONFIRMED → NEW
Ever confirmed: true
The patch seems funny, the +'s dont match up with the Addref, etc.  Can you 
submit the patch -u, and as an attachment.  Thanx.  Do you want me to check this 
in.. or just a review.
Attached a non-broken version of the patch, not sure what happened last time. I
don't have CVS write access so review and checkin would be appreciated. The only
issue for me is whether this change might trigger a leak / crash in some obscure
place (eg somone manually add-refing). The fact that Win and Gtk ref-count makes
this unlikely, and I've had the patch in my tree for over a week without
noticing any suspicous crashes.

Anyway test / commit as you see fit. Many thanks!
Blocks: 80142
r=dcone
The refcounting rules for ns{I}DrawingSurfaces are very weak, and in most places 
they are treated like a non-refcounted object. For example, 
nsRenderingContextImpl::DrawTile() does a GetDrawingSurface((void**)&theSurface), 
but never calls anything to release or destroy the surface. In addition,
nsRenderingContextMac::GetDrawingSurface doesn't addref its return value, and nor 
does nsDeviceContextMac::GetDrawingSurface(). Add to that the explicit casts 
between nsDrawingSurfaces and nsDrawingSurfaceMacs (which implement 
nsIDrawingSurface{Mac}, and you're in for a world of hurt.

I'm not going to sr this bug. dcone needs to whack the mac gfx source to make the 
ownership model of nsDrawingSurface explicit. If that means passing them around 
as interfaces, and doing proper refcounting, then that's what needs to happen.
It was written in the good ol'days before the general "COM-ification" and many 
objects that were considered "native" were not refcounted.

I agree for the refcounting, that's what this bug is about.  I would be more 
cautious about removing the static casts (we have 4 instances of static_cast<
nsDrawingSurfaceMac*>).  If you change things in these strategic places, please 
watch the performance carefully.  I recommend we file another bug for that.
I was pretty much afraid of the scenario sfraser suggests. I can keep using my
patch locally (it seems to work and I haven't noticed huge leaks). As to fixing
the correctness of nsDrawingSurface(Mac) for reference counting generally, well
as pierre said it's going to be a bit critical.

The obvious (naiive?) validation for me seems to be compare and contrast with
Gtk / Win32 implementations, and any code treating these things as
nsIDrawingSurfaces will therefore be 'safe' (I think).

That still leaves all the cases where people are working with an
nsDrawingSurfaceMac directly. 

One thought I did have for to prevent leaks was to leave the original 'delete'
call in DestroyDrawingSurface; this would be a hack but would't leak.
So, I really need some traction here. I've had this patch in my tree for nearly
3 months now, it seems to work for my browser usage. My feeling is that since
many other gfx implementations *do* ref-count (win32, gdk, and OS2), the common
code must be safe. (The Motif code also fails to ref-count, but I have no idea
if that's dead or what..)

That leaves the Mac-specific code, especially the casting between
nsIDrawingSurfaces and nsDrawingSurfaceMacs which sfraser pointed out.

Is this something I can audit, or does it have to be done by dcone? Any hints
for useful things to get movement here appreciated.
Get on IRC and bug people (politely). I'm not being funny, its just the only 
thing that actually works...
Reassigning to Pierre, since Don is Sabbatical.
Assignee: dcone → pierre
Blocks: 103889
Status: NEW → ASSIGNED
Priority: -- → P2
Target Milestone: --- → mozilla0.9.7
This is my usual 'I've had this is my tree since July, and haven't had a single
failure or crash that I can attribute to it'. I know sfraser has pointed out
potential issues that need to be addressed, but at the same time the very
minimal change in the patch does seem to work. If there's useful analysis of
suspect code in DrawingSurfaceMac or RenderingContextMac I could do to validate
the changes, please let me know.
dcone is back from sabbatical. He needs to look at this, and fix the 
nsDrawingSurface mess. Maybe Pierre could chip in too.
I checked James' patch into SVG_0_9_6_BRANCH. (This is basically a branch where 
we're trying to get a stable Mozilla 0.9.6 with SVG support on all 3 platforms. 
It's not destined for the trunk).

As for the main svg branch (SVG_20010721_BRANCH), this bug is blocking us from 
landing on the trunk. We're planning to land for 0.9.7. Is it likely that this 
bug gets sorted out by then?
If not we've got the option of 
a) landing without mac-support (and break the current trunk svg-support in the 
process)
or
b) enclosing James' patch in #ifdef MOZ_SVG's

Does anyone have any thoughts on how to proceed?
I think we should proceed with option b) for now 

b) enclosing James' patch in #ifdef MOZ_SVG's.

This is the least amount of risk. The general offscreen refcnt cleanup will have
to wait for other more critical bugs to be addressed first.





sfraser (about comment #6): On none of the other platforms does 
GetDrawingSurface() addref the surface.  I'll attach a patch that makes the 
ownership on the Mac similar to what we find elsewhere, which is required because 
nsRenderingContextImpl.cpp is XP code.  Changing the ownership on all platforms 
is out of the scope of this bug (IMO).

pink/sfraser: please r/sr
Summary: nsRenderingContextMac doesn't reference count offscreens → [review]nsRenderingContextMac doesn't reference count offscreens
Attached patch patch 2.0Splinter Review
In the proposed patch, a drawing surface is addref'd when it is created or 
selected, and released when the owning context is deleted or when another surface 
is selected.
Thanks for the work pierre, I'm glad to have someone more experienced looking at
this. Patch looks fine to me, not that that proves much. I will give it some
testing anyway.
I took the option given in comment 15 and checked this to the SVG branch with
#ifdef MOZ_SVG

The existing code got left as is. We're planning on merging the svg branch to
the trunk today; if the more complete patch gets in by then, then the hack can
be reversed.
pink/sfraser: please r/sr
I could have sworn that somewhere in the code, we treat nsDrawingSurfaces as 
casted CGrafPtrs, If I can find that, then I object to the patch. If I can't, 
then the patch is OK.
Comment on attachment 61062 [details] [diff] [review]
patch 2.0

i searched through gfx and the only places i found that used the string
"CGrafPtr" got it by calling GetGrafPtr() on the surface. r=pink
Attachment #61062 - Flags: review+
fixed on the trunk
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Target Milestone: mozilla0.9.7 → mozilla0.9.8
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: