[PATCH] fonts: Fix refcounting for asynchronous font operations (#3040)

Adam Jackson ajax at redhat.com
Mon Aug 9 12:20:20 PDT 2010


When doing Xinerama, we'll dispatch font ops across all backend screens.
If using a font server (such that some operations can sleep), we'll put
the client to sleep once for each screen, but only wake up once, because
we're trying to keep track of the sleep count in _each_ screen's
closure.

Instead, just ask the core whether the client is already asleep.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 dix/dixfonts.c     |  101 ++++++++++++++++++++++++---------------------------
 include/closestr.h |    5 ---
 2 files changed, 48 insertions(+), 58 deletions(-)

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 4a8f113..e22eabe 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -321,10 +321,10 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 	    continue;
 	}
 	if (err == Suspended) {
-	    if (!c->slept) {
-		c->slept = TRUE;
-		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
-	    }
+	    if (!ClientIsAsleep(client))
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, c);
+	    else
+		goto xinerama_sleep;
 	    return TRUE;
 	}
 	break;
@@ -373,8 +373,8 @@ bail:
 	SendErrorToClient(c->client, X_OpenFont, 0,
 			  c->fontid, FontToXError(err));
     }
-    if (c->slept)
-	ClientWakeup(c->client);
+    ClientWakeup(c->client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++) {
 	FreeFPE(c->fpe_list[i]);
     }
@@ -460,7 +460,6 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna
     c->current_fpe = 0;
     c->num_fpes = num_fpes;
     c->fnamelen = lenfname;
-    c->slept = FALSE;
     c->flags = flags;
     c->non_cachable_font = cached;
 
@@ -622,12 +621,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		 c->names);
 
 	    if (err == Suspended) {
-		if (!c->slept) {
-		    c->slept = TRUE;
+		if (!ClientIsAsleep(client))
 		    ClientSleep(client,
-			(ClientSleepProcPtr)doListFontsAndAliases,
-			(pointer) c);
-		}
+				(ClientSleepProcPtr)doListFontsAndAliases,
+				c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 
@@ -650,12 +649,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		     c->current.patlen, c->current.max_names - c->names->nnames,
 		     &c->current.private);
 		if (err == Suspended) {
-		    if (!c->slept) {
+		    if (!ClientIsAsleep(client))
 			ClientSleep(client,
 				    (ClientSleepProcPtr)doListFontsAndAliases,
-				    (pointer) c);
-			c->slept = TRUE;
-		    }
+				    c);
+		    else
+			goto xinerama_sleep;
 		    return TRUE;
 		}
 		if (err == Successful)
@@ -668,12 +667,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
 		     &resolvedlen, c->current.private);
 		if (err == Suspended) {
-		    if (!c->slept) {
+		    if (ClientIsAsleep(client))
 			ClientSleep(client,
 				    (ClientSleepProcPtr)doListFontsAndAliases,
-				    (pointer) c);
-			c->slept = TRUE;
-		    }
+				    c);
+		    else
+			goto xinerama_sleep;
 		    return TRUE;
 		}
 		if (err == FontNameAlias) {
@@ -822,8 +821,8 @@ finish:
     free(bufferStart);
 
 bail:
-    if (c->slept)
-	ClientWakeup(client);
+    ClientWakeup(client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++)
 	FreeFPE(c->fpe_list[i]);
     free(c->fpe_list);
@@ -881,7 +880,6 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
     c->current.list_started = FALSE;
     c->current.private = 0;
     c->haveSaved = FALSE;
-    c->slept = FALSE;
     c->savedName = 0;
     doListFontsAndAliases(client, c);
     return Success;
@@ -928,11 +926,11 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
 		 c->current.max_names, &c->current.private);
 	    if (err == Suspended)
  	    {
-		if (!c->slept)
- 		{
-		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
-		    c->slept = TRUE;
-		}
+		if (!ClientIsAsleep(client))
+		    ClientSleep(client,
+				(ClientSleepProcPtr)doListFontsWithInfo, c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	    if (err == Successful)
@@ -947,13 +945,11 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
 		 &numFonts, c->current.private);
 	    if (err == Suspended)
  	    {
-		if (!c->slept)
- 		{
+		if (!ClientIsAsleep(client))
 		    ClientSleep(client,
-		    	     (ClientSleepProcPtr)doListFontsWithInfo,
-			     c);
-		    c->slept = TRUE;
-		}
+				(ClientSleepProcPtr)doListFontsWithInfo, c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	}
@@ -1098,8 +1094,8 @@ finish:
 		     - sizeof(xGenericReply));
     WriteSwappedDataToClient(client, length, &finalReply);
 bail:
-    if (c->slept)
-	ClientWakeup(client);
+    ClientWakeup(client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++)
 	FreeFPE(c->fpe_list[i]);
     free(c->reply);
@@ -1154,7 +1150,6 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
     c->current.private = 0;
     c->savedNumFonts = 0;
     c->haveSaved = FALSE;
-    c->slept = FALSE;
     c->savedName = 0;
     doListFontsWithInfo(client, c);
     return Success;
@@ -1181,7 +1176,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 	fpe = c->pGC->font->fpe;
 	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
 
-	if (c->slept)
+	if (ClientIsAsleep(client))
 	{
 	    /* Client has died, but we cannot bail out right now.  We
 	       need to clean up after the work we did when going to
@@ -1198,7 +1193,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
     }
 
     /* Make sure our drawable hasn't disappeared while we slept. */
-    if (c->slept && c->pDraw)
+    if (ClientIsAsleep(client) && c->pDraw)
     {
 	DrawablePtr pDraw;
 	dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
@@ -1212,7 +1207,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 	}
     }
 
-    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+    client_state = ClientIsAsleep(client) ? SLEEPING : NEVER_SLEPT;
 
     while (c->endReq - c->pElt > TextEltHeader)
     {
@@ -1295,7 +1290,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 
 	    if (lgerr == Suspended)
 	    {
-		if (!c->slept) {
+		if (!ClientIsAsleep(client)) {
 		    int len;
 		    GC *pGC;
 		    PTclosurePtr new_closure;
@@ -1368,15 +1363,14 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 		    c->pGC = pGC;
 		    ValidateGC(c->pDraw, c->pGC);
 		    
-		    c->slept = TRUE;
-		    ClientSleep(client,
-		    	     (ClientSleepProcPtr)doPolyText,
-			     (pointer) c);
+		    ClientSleep(client, (ClientSleepProcPtr)doPolyText, c);
 
 		    /* Set up to perform steps 3 and 4 */
 		    client_state = START_SLEEP;
 		    continue;	/* on to steps 3 and 4 */
 		}
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	    else if (lgerr != Successful)
@@ -1419,9 +1413,10 @@ bail:
 #endif
 	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
     }
-    if (c->slept)
+    if (ClientIsAsleep(client))
     {
 	ClientWakeup(c->client);
+xinerama_sleep:
 	ChangeGC(NullClient, c->pGC, clearGCmask, clearGC);
 
 	/* Unreference the font from the scratch GC */
@@ -1460,7 +1455,6 @@ PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
     local_closure.pGC = pGC;
     local_closure.did = did;
     local_closure.err = Success;
-    local_closure.slept = FALSE;
 
     (void) doPolyText(client, &local_closure);
     return Success;
@@ -1485,7 +1479,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
     }
 
     /* Make sure our drawable hasn't disappeared while we slept. */
-    if (c->slept && c->pDraw)
+    if (ClientIsAsleep(client) && c->pDraw)
     {
 	DrawablePtr pDraw;
 	dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
@@ -1502,7 +1496,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
     lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
     if (lgerr == Suspended)
     {
-        if (!c->slept) {
+        if (!ClientIsAsleep(client)) {
 	    GC *pGC;
 	    unsigned char *data;
 	    ITclosurePtr new_closure;
@@ -1555,9 +1549,10 @@ doImageText(ClientPtr client, ITclosurePtr c)
 	    c->pGC = pGC;
 	    ValidateGC(c->pDraw, c->pGC);
 
-	    c->slept = TRUE;
-            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, c);
         }
+	else
+	    goto xinerama_sleep;
         return TRUE;
     }
     else if (lgerr != Successful)
@@ -1576,9 +1571,10 @@ bail:
     if (err != Success && c->client != serverClient) {
 	SendErrorToClient(c->client, c->reqType, 0, 0, err);
     }
-    if (c->slept)
+    if (ClientIsAsleep(client))
     {
 	ClientWakeup(c->client);
+xinerama_sleep:
 	ChangeGC(NullClient, c->pGC, clearGCmask, clearGC);
 
 	/* Unreference the font from the scratch GC */
@@ -1616,7 +1612,6 @@ ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
 	local_closure.itemSize = 2;
     }
     local_closure.did = did;
-    local_closure.slept = FALSE;
 
     (void) doImageText(client, &local_closure);
     return Success;
diff --git a/include/closestr.h b/include/closestr.h
index 2cd67b1..7ca2613 100644
--- a/include/closestr.h
+++ b/include/closestr.h
@@ -46,7 +46,6 @@ typedef struct _OFclosure {
     short       num_fpes;
     FontPathElementPtr *fpe_list;
     Mask        flags;
-    Bool        slept;
 
 /* XXX -- get these from request buffer instead? */
     char       *origFontName;
@@ -79,7 +78,6 @@ typedef struct _LFWIclosure {
     LFWIstateRec	saved;
     int			savedNumFonts;
     Bool		haveSaved;
-    Bool		slept;
     char		*savedName;
 } LFWIclosureRec;
 
@@ -93,7 +91,6 @@ typedef struct _LFclosure {
     LFWIstateRec current;
     LFWIstateRec saved;
     Bool        haveSaved;
-    Bool        slept;
     char	*savedName;
     int		savedNameLen;
 }	LFclosureRec;
@@ -124,7 +121,6 @@ typedef struct _PTclosure {
     int			itemSize;
     XID			did;
     int			err;
-    Bool		slept;
 } PTclosureRec;
 
 /* ImageText */
@@ -151,6 +147,5 @@ typedef struct _ITclosure {
     ImageTextPtr	imageText;
     int			itemSize;
     XID			did;
-    Bool		slept;
 } ITclosureRec;
 #endif				/* CLOSESTR_H */
-- 
1.7.2



More information about the xorg-devel mailing list