diff options
| author | Kristian Høgsberg <krh@bitplanet.net> | 2010-07-22 21:11:02 -0400 | 
|---|---|---|
| committer | Kristian Høgsberg <krh@bitplanet.net> | 2010-07-22 21:11:20 -0400 | 
| commit | ab434f6b7641a64d30725a9ac24929240362d466 (patch) | |
| tree | 239ee2ff7b3078f5af5fd17b25f3cfec991af5e2 | |
| parent | c20a3628c7c6b7c41efe309b712bf93eb4e92039 (diff) | |
glx: Use _Xglobal_lock for protecting extension display list
Avoids double locking glXLock in the X wire to event handlers.
| -rw-r--r-- | src/glx/dri2.c | 4 | ||||
| -rw-r--r-- | src/glx/glxclient.h | 4 | ||||
| -rw-r--r-- | src/glx/glxext.c | 204 | 
3 files changed, 86 insertions, 126 deletions
| diff --git a/src/glx/dri2.c b/src/glx/dri2.c index ab530baf0f..d53431c19a 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -88,7 +88,7 @@ static Bool  DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)  {     XExtDisplayInfo *info = DRI2FindDisplay(dpy); -   XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); +   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);     XextCheckExtension(dpy, info, dri2ExtensionName, False); @@ -107,7 +107,7 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)  	 return False;        aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); -      aevent->type = glx_info->codes->first_event + GLX_BufferSwapComplete; +      aevent->type = glx_dpy->codes->first_event + GLX_BufferSwapComplete;        aevent->send_event = (awire->type & 0x80) != 0;        aevent->display = dpy;        aevent->drawable = awire->drawable; diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 26f28852ce..4f833057ff 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -557,6 +557,10 @@ struct __GLXscreenConfigsRec   */  struct __GLXdisplayPrivateRec  { +   /* The extension protocol codes */ +   XExtCodes *codes; +   struct __GLXdisplayPrivateRec *next; +      /**       * Back pointer to the display       */ diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 9c3c7a4840..88e74c2a38 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -68,13 +68,8 @@ _X_HIDDEN int __glXDebug = 0;  /* Extension required boiler plate */ -static char *__glXExtensionName = GLX_EXTENSION_NAME; -#ifdef GLX_USE_APPLEGL -static XExtensionInfo __glXExtensionInfo_data; -XExtensionInfo *__glXExtensionInfo = &__glXExtensionInfo_data; -#else -XExtensionInfo *__glXExtensionInfo = NULL; -#endif +static const char __glXExtensionName[] = GLX_EXTENSION_NAME; +static __GLXdisplayPrivate *glx_displays;  static /* const */ char *error_list[] = {     "GLXBadContext", @@ -92,21 +87,6 @@ static /* const */ char *error_list[] = {     "GLXBadWindow",  }; -static int -__glXCloseDisplay(Display * dpy, XExtCodes * codes) -{ -   GLXContext gc; - -   gc = __glXGetCurrentContext(); -   if (dpy == gc->currentDpy) { -      __glXSetCurrentContextNull(); -      __glXFreeContext(gc); -   } - -   return XextRemoveDisplay(__glXExtensionInfo, dpy); -} - -  #ifdef GLX_USE_APPLEGL  static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes,                                 char *buf, int n); @@ -115,29 +95,14 @@ static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes,  static  XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,                             __GLX_NUMBER_ERRORS, error_list) + +static int +__glXCloseDisplay(Display * dpy, XExtCodes * codes);  static Bool  __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);  static Status  __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); -static /* const */ XExtensionHooks __glXExtensionHooks = { -  NULL,                   /* create_gc */ -  NULL,                   /* copy_gc */ -  NULL,                   /* flush_gc */ -  NULL,                   /* free_gc */ -  NULL,                   /* create_font */ -  NULL,                   /* free_font */ -  __glXCloseDisplay,      /* close_display */ -  __glXWireToEvent,       /* wire_to_event */ -  __glXEventToWire,       /* event_to_wire */ -  NULL,                   /* error */ -  __glXErrorString,       /* error_string */ -}; - -XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, -                           __glXExtensionName, &__glXExtensionHooks, -                           __GLX_NUMBER_EVENTS, NULL) -  /*   * GLX events are a bit funky.  We don't stuff the X event code into   * our user exposed (via XNextEvent) structure.  Instead we use the GLX @@ -150,11 +115,12 @@ XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,  static Bool  __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)  { -   XExtDisplayInfo *info = __glXFindDisplay(dpy); +   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); -   XextCheckExtension(dpy, info, __glXExtensionName, False); +   if (glx_dpy == NULL) +      return False; -   switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { +   switch ((wire->u.u.type & 0x7f) - glx_dpy->codes->first_event) {     case GLX_PbufferClobber:     {        GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event; @@ -209,9 +175,10 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)  static Status  __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)  { -   XExtDisplayInfo *info = __glXFindDisplay(dpy); +   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); -   XextCheckExtension(dpy, info, __glXExtensionName, False); +   if (glx_dpy == NULL) +      return False;     switch (event->type) {     case GLX_DAMAGED: @@ -279,20 +246,32 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)  ** structure.  The caller will free the extension structure.  */  static int -__glXFreeDisplayPrivate(XExtData * extension) +__glXCloseDisplay(Display * dpy, XExtCodes * codes)  { -   __GLXdisplayPrivate *priv; +   __GLXdisplayPrivate *priv, **prev; +   GLXContext gc; + +   _XLockMutex(_Xglobal_lock); +   prev = &glx_displays; +   for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) { +      if (priv->dpy == dpy) { +	 (*prev)->next = priv->next; +	 break; +      } +   } +   _XUnlockMutex(_Xglobal_lock); + +   gc = __glXGetCurrentContext(); +   if (dpy == gc->currentDpy) { +      __glXSetCurrentContextNull(); +      __glXFreeContext(gc); +   } -   priv = (__GLXdisplayPrivate *) extension->private_data;     FreeScreenConfigs(priv); -   if (priv->serverGLXvendor) { +   if (priv->serverGLXvendor)        Xfree((char *) priv->serverGLXvendor); -      priv->serverGLXvendor = 0x0;      /* to protect against double free's */ -   } -   if (priv->serverGLXversion) { +   if (priv->serverGLXversion)        Xfree((char *) priv->serverGLXversion); -      priv->serverGLXversion = 0x0;     /* to protect against double free's */ -   }     __glxHashDestroy(priv->drawHash); @@ -312,10 +291,9 @@ __glXFreeDisplayPrivate(XExtData * extension)  #endif     Xfree((char *) priv); -   return 0; -} -/************************************************************************/ +   return 1; +}  /*  ** Query the version of the GLX extension.  This procedure works even if @@ -819,67 +797,52 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)  _X_HIDDEN __GLXdisplayPrivate *  __glXInitialize(Display * dpy)  { -   XExtDisplayInfo *info = __glXFindDisplay(dpy); -   XExtData **privList, *private, *found;     __GLXdisplayPrivate *dpyPriv; -   XEDataObject dataObj; -   int major, minor;  #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)     Bool glx_direct, glx_accel;  #endif +   int i; -   /* The one and only long long lock */ -   __glXLock(); +   _XLockMutex(_Xglobal_lock); -   if (!XextHasExtension(info)) { -      /* No GLX extension supported by this server. Oh well. */ -      __glXUnlock(); -      XMissingExtension(dpy, __glXExtensionName); -      return 0; +   for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) { +      if (dpyPriv->dpy == dpy) { +	 _XUnlockMutex(_Xglobal_lock); +	 return dpyPriv; +      }     } -   /* See if a display private already exists.  If so, return it */ -   dataObj.display = dpy; -   privList = XEHeadOfExtensionList(dataObj); -   found = XFindOnExtensionList(privList, info->codes->extension); -   if (found) { -      __glXUnlock(); -      return (__GLXdisplayPrivate *) found->private_data; +   dpyPriv = Xcalloc(1, sizeof *dpyPriv); +   if (!dpyPriv) +      return NULL; + +   dpyPriv->codes = XInitExtension(dpy, __glXExtensionName); +   if (!dpyPriv->codes) { +      Xfree(dpyPriv); +      _XUnlockMutex(_Xglobal_lock); +      return NULL;     } +   dpyPriv->dpy = dpy; +   dpyPriv->majorOpcode = dpyPriv->codes->major_opcode; +   dpyPriv->serverGLXvendor = 0x0; +   dpyPriv->serverGLXversion = 0x0; +     /* See if the versions are compatible */ -   if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) { -      /* The client and server do not agree on versions.  Punt. */ -      __glXUnlock(); -      return 0; +   if (!QueryVersion(dpy, dpyPriv->majorOpcode, +		     &dpyPriv->majorVersion, &dpyPriv->minorVersion)) { +      Xfree(dpyPriv); +      _XUnlockMutex(_Xglobal_lock); +      return NULL;     } -   /* -    ** Allocate memory for all the pieces needed for this buffer. -    */ -   private = (XExtData *) Xmalloc(sizeof(XExtData)); -   if (!private) { -      __glXUnlock(); -      return 0; -   } -   dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); -   if (!dpyPriv) { -      __glXUnlock(); -      Xfree((char *) private); -      return 0; +   for (i = 0; i < __GLX_NUMBER_EVENTS; i++) { +      XESetWireToEvent(dpy, dpyPriv->codes->first_event + i, __glXWireToEvent); +      XESetEventToWire(dpy, dpyPriv->codes->first_event + i, __glXEventToWire);     } -   /* -    ** Init the display private and then read in the screen config -    ** structures from the server. -    */ -   dpyPriv->majorOpcode = info->codes->major_opcode; -   dpyPriv->majorVersion = major; -   dpyPriv->minorVersion = minor; -   dpyPriv->dpy = dpy; - -   dpyPriv->serverGLXvendor = 0x0; -   dpyPriv->serverGLXversion = 0x0; +   XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay); +   XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);  #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)     glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL); @@ -899,32 +862,25 @@ __glXInitialize(Display * dpy)     if (glx_direct)        dpyPriv->driswDisplay = driswCreateDisplay(dpy);  #endif +  #ifdef GLX_USE_APPLEGL -   if (apple_init_glx(dpy) || !AllocAndFetchScreenConfigs(dpy, dpyPriv)) { -#else -   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { +   if (apple_init_glx(dpy)) { +      Xfree(dpyPriv); +      return NULL; +   }  #endif -      __glXUnlock(); -      Xfree((char *) dpyPriv); -      Xfree((char *) private); -      return 0; +   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { +      Xfree(dpyPriv); +      return NULL;     } -   /* -    ** Fill in the private structure.  This is the actual structure that -    ** hangs off of the Display structure.  Our private structure is -    ** referred to by this structure.  Got that? -    */ -   private->number = info->codes->extension; -   private->next = 0; -   private->free_private = __glXFreeDisplayPrivate; -   private->private_data = (char *) dpyPriv; -   XAddToExtensionList(privList, private); - -   if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) { +   if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1)        __glXClientInfo(dpy, dpyPriv->majorOpcode); -   } -   __glXUnlock(); + +   dpyPriv->next = glx_displays; +   glx_displays = dpyPriv; + +    _XUnlockMutex(_Xglobal_lock);     return dpyPriv;  } | 
