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