[Xcb] [Bug 27368] New: XCB deadlocks in multi-threaded use

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Mon Mar 29 22:41:49 PDT 2010


http://bugs.freedesktop.org/show_bug.cgi?id=27368

           Summary: XCB deadlocks in multi-threaded use
           Product: XCB
           Version: unspecified
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: medium
         Component: Protocol
        AssignedTo: xcb at lists.freedesktop.org
        ReportedBy: nick.allen at onlinehome.de
         QAContact: xcb at lists.freedesktop.org


Every now and then our application deadlocks and xcb_wait_for_reply does not
return. I am doing an xcb_flush prior to every xcb_wait_for_event call.

I have attached the protocol trace obtained with xtrace and also a stack trace
from gdb using "thread apply all bt full". It seems that GDB did not pick up
the debugging symbols installed. Unfortunately, I could not run it with the
debug libraries explicitly by setting the LD_LIBRARY_PATH as the JVM then
crashed in Sun's native code trying to load the library.

The hang happens mostly when I call xcb_property_changed from the property
utils library (I have 0.3.6-1 package installed on Ubuntu 9.10). Very rarely it
also happens inside xcb_wait_for_event. In this trace it was inside
xcb_property_changed again and I will try to get a trace of it inside
xcb_wait_for_event as well.

Our event loop looks like this:

int finished = 0;
   xcb_generic_event_t* event;

   while (!finished)
   {
      xcb_flush(connection);
      event = xcb_wait_for_event(connection);

      if (event == NULL)
      {
         printf("Connection broken\n");
         break;
      }

      switch (event->response_type & 0x7f)
      {
      case XCB_EXPOSE:
      {
         xcb_expose_event_t* exposeEvent = (xcb_expose_event_t*)event;
         handleExposedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay, exposeEvent->window),
               exposeEvent->x,
               exposeEvent->y,
               exposeEvent->width,
               exposeEvent->height);
      }
         break;

      case XCB_BUTTON_PRESS:
      {
         xcb_button_press_event_t* buttonPressEvent =
(xcb_button_press_event_t*)event;
         handleMouseButtonPressedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay,
buttonPressEvent->event),
               buttonPressEvent->state,
               buttonPressEvent->detail,
               buttonPressEvent->event_x,
               buttonPressEvent->event_y);
      }
         break;

      case XCB_BUTTON_RELEASE:
      {
         xcb_button_release_event_t* buttonReleaseEvent =
(xcb_button_release_event_t*)event;
         handleMouseButtonReleasedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay,
buttonReleaseEvent->event),
               buttonReleaseEvent->state,
               buttonReleaseEvent->detail,
               buttonReleaseEvent->event_x,
               buttonReleaseEvent->event_y);
      }
         break;

      case XCB_MOTION_NOTIFY:
      {
         xcb_motion_notify_event_t* mouseMoveEvent =
(xcb_motion_notify_event_t*)event;
         handleMouseMovedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay,
mouseMoveEvent->event),
               mouseMoveEvent->state,
               mouseMoveEvent->event_x,
               mouseMoveEvent->event_y);
      }
         break;

      case XCB_KEY_PRESS:
      {
         xcb_key_press_event_t* keyPressEvent = (xcb_key_press_event_t*)event;
         xcb_keysym_t keySymbol = xcb_key_press_lookup_keysym(keySymbols,
keyPressEvent, 0);

         handleKeyPressedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay, keyPressEvent->event),
               connection,
               keyPressEvent->state,
               keySymbol,
               0);
      }
      break;

      case XCB_KEY_RELEASE:
      {
         xcb_key_release_event_t* keyReleaseEvent =
(xcb_key_release_event_t*)event;
         xcb_keysym_t keySymbol = xcb_key_release_lookup_keysym(keySymbols,
keyReleaseEvent, 0);

         handleKeyReleasedEvent(
            env,
            getTopLevelWindowHandle(env, javaDisplay, keyReleaseEvent->event),
            connection,
            keyReleaseEvent->state,
            keySymbol);
     }
     break;

      case XCB_CONFIGURE_NOTIFY:
      {
         xcb_configure_notify_event_t* configureEvent =
(xcb_configure_notify_event_t*)event;
         handleWindowResizedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay,
configureEvent->window),
               configureEvent->width,
               configureEvent->height);

         handleWindowMovedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay,
configureEvent->window),
               configureEvent->x,
               configureEvent->y);
      }
      break;

      case XCB_CLIENT_MESSAGE:
      {
         xcb_client_message_event_t* clientEvent =
(xcb_client_message_event_t*)event;

         if (clientEvent->type == displayData->WM_PROTOCOLS_ATOM)
         {
            if (clientEvent->data.data32[0] ==
displayData->WM_DELETE_WINDOW_ATOM)
            {
               handleCloseWindowRequestEvent(
                     env,
                     getTopLevelWindowHandle(env, javaDisplay,
clientEvent->window));
            }
            else if (clientEvent->data.data32[0] ==
displayData->NET_WM_PING_ATOM)
            {
               respondToPing(connection, screen->root, clientEvent);
            }
         }
         else if (clientEvent->type == displayData->SHUTDOWN_EVENT_ATOM)
         {
            finished = 1;
         }
      }
      break;

      case XCB_PROPERTY_NOTIFY:
      {
         xcb_property_notify_event_t* propertyEvent =
(xcb_property_notify_event_t*)event;

         xcb_property_changed(&propertyHandlers, propertyEvent->state,
propertyEvent->window, propertyEvent->atom);
      }
      break;

      case XCB_MAP_NOTIFY:
      {
         xcb_map_notify_event_t* mapEvent = (xcb_map_notify_event_t*)event;

         handleWindowShownEvent(env, getTopLevelWindowHandle(env, javaDisplay,
mapEvent->event));
      }
      break;

      case XCB_FOCUS_IN:
      {
         xcb_focus_in_event_t* focusEvent = (xcb_focus_in_event_t*)event;
         handleWindowActivatedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay, focusEvent->event));
      }
      break;

      case XCB_FOCUS_OUT:
      {
         xcb_focus_out_event_t* focusEvent = (xcb_focus_out_event_t*)event;
         handleWindowDeactivatedEvent(
               env,
               getTopLevelWindowHandle(env, javaDisplay, focusEvent->event));
      }
      break;

      default: /* unknown event type - ignore it. */
         printf("Unknown event type %d\n", (int)event->response_type);
      break;
      }

      if (env->ExceptionOccurred())
      {
         env->ExceptionDescribe();
         env->ExceptionClear();
      }
   }


-- 
Configure bugmail: http://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the Xcb mailing list