summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2008-10-08 16:50:43 -0400
committerDavid Reveman <davidr@novell.com>2008-10-30 03:37:51 -0400
commit051d638d9dec8d4b18bd2d8ce9c603a290718ffa (patch)
treeb8e0438e5c0ff7f876c7a8656ff956afd552e05e
parent8b167b13dc8355ced1c734a4b87e92017e3f1ed1 (diff)
Proper prefetching of required back-end server atoms.
-rw-r--r--hw/dmx/dmx.h10
-rw-r--r--hw/dmx/dmxatom.c234
-rw-r--r--hw/dmx/dmxatom.h1
-rw-r--r--hw/dmx/dmxscrinit.c5
4 files changed, 181 insertions, 69 deletions
diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h
index 3a50391ac..6a2aafcac 100644
--- a/hw/dmx/dmx.h
+++ b/hw/dmx/dmx.h
@@ -88,6 +88,11 @@ typedef enum {
PosRelative
} PositionType;
+typedef struct _DMXAtom {
+ Atom atom;
+ xcb_intern_atom_cookie_t cookie;
+} DMXAtom;
+
typedef struct _DMXSequence {
struct _DMXSequence *next;
unsigned long sequence;
@@ -156,8 +161,9 @@ typedef struct _DMXScreenInfo {
Atom *atomTable;
int atomTableSize;
- Atom *beAtomTable;
- int beAtomTableSize;
+
+ DMXAtom *beAtomTable;
+ int beAtomTableSize;
Display *beDisplay; /**< Back-end X server's display */
int beWidth; /**< Width of BE display */
diff --git a/hw/dmx/dmxatom.c b/hw/dmx/dmxatom.c
index 74da52e05..bfbc30dc6 100644
--- a/hw/dmx/dmxatom.c
+++ b/hw/dmx/dmxatom.c
@@ -29,108 +29,208 @@
#include "dmxatom.h"
#include "dmxsync.h"
+#include "dmxscrinit.h"
-Atom
-dmxAtom (DMXScreenInfo *dmxScreen,
- Atom beAtom)
+static void
+dmxAddAtom (DMXScreenInfo *dmxScreen,
+ Atom atom,
+ Atom beAtom)
{
- Atom atom = None;
+ int i;
- if (beAtom < dmxScreen->beAtomTableSize)
- atom = dmxScreen->beAtomTable[beAtom];
-
- if (!atom)
+ if (atom >= dmxScreen->beAtomTableSize)
{
- xcb_get_atom_name_reply_t *reply;
+ DMXAtom *table;
- reply =
- xcb_get_atom_name_reply (dmxScreen->connection,
- xcb_get_atom_name (dmxScreen->connection,
- beAtom),
- NULL);
- if (!reply)
- return None;
-
- atom = MakeAtom ((char *) (reply + 1), reply->name_len, TRUE);
+ table = xrealloc (dmxScreen->beAtomTable,
+ sizeof (DMXAtom) * (atom + 1));
+ if (table)
+ {
+ for (i = dmxScreen->beAtomTableSize; i < atom; i++)
+ {
+ table[i].atom = None;
+ table[i].cookie.sequence = 0;
+ }
- free (reply);
+ table[atom].atom = beAtom;
+ table[atom].cookie.sequence = 0;
- if (!atom)
- return None;
+ dmxScreen->beAtomTable = table;
+ dmxScreen->beAtomTableSize = atom + 1;
+ }
+ }
+ else
+ {
+ dmxScreen->beAtomTable[atom].atom = beAtom;
+ }
- if (beAtom >= dmxScreen->beAtomTableSize)
+ if (beAtom)
+ {
+ if (beAtom >= dmxScreen->atomTableSize)
{
Atom *table;
- int i;
- table = xrealloc (dmxScreen->beAtomTable,
+ table = xrealloc (dmxScreen->atomTable,
sizeof (Atom) * (beAtom + 1));
- if (!table)
- return atom;
+ if (table)
+ {
+ for (i = dmxScreen->atomTableSize; i < beAtom; i++)
+ table[i] = None;
- for (i = dmxScreen->beAtomTableSize; i < beAtom; i++)
- table[i] = None;
+ table[beAtom] = atom;
- dmxScreen->beAtomTable = table;
- dmxScreen->beAtomTableSize = beAtom + 1;
+ dmxScreen->atomTable = table;
+ dmxScreen->atomTableSize = beAtom + 1;
+ }
+ }
+ else
+ {
+ dmxScreen->atomTable[beAtom] = atom;
}
-
- dmxScreen->beAtomTable[beAtom] = atom;
}
-
- return atom;
}
-Atom
-dmxBEAtom (DMXScreenInfo *dmxScreen,
- Atom atom)
+static void
+dmxInternAtomReply (ScreenPtr pScreen,
+ unsigned int sequence,
+ xcb_generic_reply_t *reply,
+ xcb_generic_error_t *error,
+ void *data)
{
- Atom beAtom = None;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Atom atom = (Atom) data;
- if (atom < dmxScreen->atomTableSize)
- beAtom = dmxScreen->atomTable[atom];
+ dmxScreen->beAtomTable[atom].cookie.sequence = 0;
- if (!beAtom)
+ if (reply)
{
- xcb_intern_atom_reply_t *reply;
- char *name;
+ xcb_intern_atom_reply_t *xatom = (xcb_intern_atom_reply_t *) reply;
+
+ dmxAddAtom (dmxScreen, atom, xatom->atom);
+ }
+}
+
+static unsigned int
+dmxBERequestAtom (DMXScreenInfo *dmxScreen,
+ Atom atom)
+{
+ if (atom < dmxScreen->beAtomTableSize)
+ if (dmxScreen->beAtomTable[atom].atom)
+ return 0;
+
+ if (atom <= XA_LAST_PREDEFINED)
+ {
+ dmxAddAtom (dmxScreen, atom, atom);
+ }
+ else
+ {
+ char *name;
+
+ dmxAddAtom (dmxScreen, atom, None);
name = NameForAtom (atom);
- if (!name)
- return None;
+ if (name && atom < dmxScreen->beAtomTableSize)
+ {
+ dmxScreen->beAtomTable[atom].cookie =
+ xcb_intern_atom (dmxScreen->connection,
+ FALSE,
+ strlen (name),
+ name);
+
+ return dmxScreen->beAtomTable[atom].cookie.sequence;
+ }
+ }
+
+ return 0;
+}
+
+Atom
+dmxAtom (DMXScreenInfo *dmxScreen,
+ Atom beAtom)
+{
+ if (beAtom < dmxScreen->atomTableSize)
+ if (dmxScreen->atomTable[beAtom])
+ return dmxScreen->atomTable[beAtom];
+
+ if (beAtom <= XA_LAST_PREDEFINED)
+ {
+ dmxAddAtom (dmxScreen, beAtom, beAtom);
+ }
+ else
+ {
+ xcb_get_atom_name_reply_t *reply;
+ Atom atom;
- reply = xcb_intern_atom_reply (dmxScreen->connection,
- xcb_intern_atom (dmxScreen->connection,
- FALSE,
- strlen (name),
- name),
- NULL);
+ reply = xcb_get_atom_name_reply
+ (dmxScreen->connection,
+ xcb_get_atom_name (dmxScreen->connection,
+ beAtom),
+ NULL);
if (!reply)
return None;
- beAtom = reply->atom;
+ atom = MakeAtom ((char *) (reply + 1), reply->name_len, TRUE);
free (reply);
- if (atom >= dmxScreen->atomTableSize)
- {
- Atom *table;
- int i;
+ if (!atom)
+ return None;
- table = xrealloc (dmxScreen->atomTable,
- sizeof (Atom) * (atom + 1));
- if (!table)
- return beAtom;
+ dmxAddAtom (dmxScreen, atom, beAtom);
+ }
- for (i = dmxScreen->atomTableSize; i < atom; i++)
- table[i] = None;
+ if (beAtom < dmxScreen->atomTableSize)
+ return dmxScreen->atomTable[beAtom];
- dmxScreen->atomTable = table;
- dmxScreen->atomTableSize = atom + 1;
- }
+ return None;
+}
+
+Atom
+dmxBEAtom (DMXScreenInfo *dmxScreen,
+ Atom atom)
+{
+ xcb_intern_atom_cookie_t cookie = { 0 };
+
+ if (atom < dmxScreen->beAtomTableSize)
+ {
+ if (dmxScreen->beAtomTable[atom].atom)
+ return dmxScreen->beAtomTable[atom].atom;
- dmxScreen->atomTable[atom] = beAtom;
+ cookie = dmxScreen->beAtomTable[atom].cookie;
}
- return beAtom;
+ if (!cookie.sequence)
+ cookie.sequence = dmxBERequestAtom (dmxScreen, atom);
+
+ if (cookie.sequence)
+ {
+ xcb_intern_atom_reply_t *reply;
+
+ reply = xcb_intern_atom_reply (dmxScreen->connection, cookie, NULL);
+
+ dmxInternAtomReply (screenInfo.screens[dmxScreen->index],
+ cookie.sequence,
+ (xcb_generic_reply_t *) reply,
+ NULL,
+ (void *) atom);
+ }
+
+ if (atom < dmxScreen->beAtomTableSize)
+ return dmxScreen->beAtomTable[atom].atom;
+
+ return None;
+}
+
+void
+dmxBEPrefetchAtom (DMXScreenInfo *dmxScreen,
+ Atom atom)
+{
+ unsigned int sequence;
+
+ sequence = dmxBERequestAtom (dmxScreen, atom);
+ if (sequence)
+ dmxAddRequest (&dmxScreen->request,
+ dmxInternAtomReply,
+ sequence,
+ (void *) atom);
}
diff --git a/hw/dmx/dmxatom.h b/hw/dmx/dmxatom.h
index b1ca43412..88416b3d2 100644
--- a/hw/dmx/dmxatom.h
+++ b/hw/dmx/dmxatom.h
@@ -30,5 +30,6 @@
extern Atom dmxAtom (DMXScreenInfo *dmxScreen, Atom beAtom);
extern Atom dmxBEAtom (DMXScreenInfo *dmxScreen, Atom atom);
+extern void dmxBEPrefetchAtom (DMXScreenInfo *dmxScreen, Atom atom);
#endif /* DMXATOM_H */
diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index 36d9c69c6..c7a3a1951 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -143,6 +143,11 @@ void dmxBEScreenInit(ScreenPtr pScreen)
dmxScreen->selectionOwner = None;
sprintf(buf, "DMX_%s", dmxDigest);
+
+ /* prefetch all valid atoms */
+ for (i = 1; ValidAtom ((Atom) i); i++);
+ while (--i)
+ dmxBEPrefetchAtom (dmxScreen, (Atom) i);
XLIB_PROLOGUE (dmxScreens);
dmxScreen->beSelectionAtom = XInternAtom (dmxScreen->beDisplay, buf, 0);