Commit 3ab6cd31 authored by Adam Jackson's avatar Adam Jackson Committed by Keith Packard

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

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: default avatarAdam Jackson <ajax@redhat.com>
Reviewed-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 35c0dbe4
......@@ -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;
......
......@@ -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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment