<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - There is no way to cancel wl_display_dispatch(_pending) call without a server roundtrip"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=91766">91766</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>There is no way to cancel wl_display_dispatch(_pending) call without a server roundtrip
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>Wayland
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>medium
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>wayland
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>wayland-bugs@lists.freedesktop.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>jadahl@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Assuming a client is using a multi threaded UI architecture, dispatching on
more than one thread, either using the example API usage
(wl_display_prepare_read(), poll(fds, 1, -1), ...) or the API helpers
wl_display_dispatch() and wl_display_dispatch_queue(), there is currently now
good way to make the dispatch call return so that the client can disconnect.

Calling wl_display_disconnect() simply closes the fd and frees the wl_display
structure, causing the poll() call to stall and likely a segmentation fault if
it leaves it.

Calling pthread_kill() does not work as is, since wl_display_dispatch_queue()
will simply re-poll on EINTR.

What one can do is to set a variable causing the dispatcher thread not to
continue dispatching and then call wl_display_sync(). This would make the
server write data to the fd, causing the dispatcher thread to dispatch and
return. This should IMHO only be considered a temporary work-around.

Potentially better solutions could be:

1) Make sure wl_display_disconnect() waits for all registered readers to
finish, while making the readers using the helpers cancel using some fd
signaling technique like eventfd. A problem with this is that the
wl_display_dispatch(_queue) functions would need to return an error (maybe
ECANCELED is a reasonable one) This has the side effect that existing clients
doing poll(1, -1) and calling wl_display_disconnect() would suddenly start to
dead lock. The dead lock could be avoided however by only waiting for
wl_display_dispatch_pending() callers, meaning letting the other ones simply
continue to deadlock and/or crash in their dispatcher thread as they would
before.

2) Introduce new API for canceling wl_display_dispatch(_queue), letting
wl_display_disconnect() stay thread unsafe, using some method similar to above.
Similar issues as above, but without changing the behavior of
wl_display_disconnect().</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>