Mir client callbacks are not thread-safe
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Mir |
Triaged
|
Medium
|
Unassigned | ||
mir (Ubuntu) |
Triaged
|
Medium
|
Unassigned |
Bug Description
Mir clients may not be aware, but the callbacks made by libmirclient are not thread safe in any way.
An apparently simple single-threaded Mir client has 3 threads, which can execute concurrently:
1. The "main" thread, where the initial connection was made.
2. The socket thread, where the protocol is handled (mir_connected_
3. The input thread, where input events are received (MirMotionEvent, MirKeyEvent)
Yes, you could receive a MirSurfaceEvent and MirMotionEvent simultaneously in different threads. Neither of which are the main thread.
This is how a Mir client works. Unfortunately the existence of these threads is not yet documented. I will update the docs. But this bug is really about finding a way to make the client API more thread safe for simple toolkits and clients that normally don't care about threads. UPDATE: Client API docs improved in r789.
To make matters worse, the client API functions are generally not thread safe either: mir_surface_* mir_connection_*. So libmirclient forces you to run in multiple threads and yet doesn't protect you at all against races and corruption that could arise from calling libmirclient from varying threads. UPDATE: Fixed in r827
Related branches
- PS Jenkins bot (community): Approve (continuous-integration)
- Mir development team: Pending requested
-
Diff: 346 lines (+182/-18)6 files modifiedexamples/fingerpaint.c (+4/-2)
include/client/mir_toolkit/mir_client_library.h (+22/-0)
src/client/mir_client_library.cpp (+10/-0)
src/client/mir_surface.cpp (+33/-12)
src/client/mir_surface.h (+8/-4)
tests/acceptance-tests/test_client_library.cpp (+105/-0)
- Mir development team: Pending requested
-
Diff: 564 lines (+265/-58)10 files modifiedexamples/eglapp.c (+9/-9)
examples/fingerpaint.c (+23/-23)
examples/progressbar.c (+30/-25)
include/client/mir_toolkit/mir_client_library.h (+8/-0)
include/shared/mir_toolkit/client_types.h (+1/-0)
include/shared/mir_toolkit/event.h (+2/-1)
src/client/CMakeLists.txt (+1/-0)
src/client/mir_client_library.cpp (+51/-0)
src/client/mir_event_queue.cpp (+88/-0)
src/client/mir_event_queue.h (+52/-0)
summary: |
- Event callbacks are made in a different thread + Event callbacks are not single-thread-safe |
Changed in mir: | |
assignee: | nobody → Daniel van Vugt (vanvugt) |
Changed in mir: | |
status: | New → In Progress |
Changed in mir: | |
importance: | High → Medium |
Changed in mir: | |
milestone: | 0.0.4 → 0.0.5 |
Changed in mir: | |
milestone: | 0.0.5 → 0.0.6 |
summary: |
- Event callbacks are not single-thread-safe + Mir client callbacks are not thread-safe |
description: | updated |
Changed in mir: | |
status: | In Progress → Triaged |
description: | updated |
description: | updated |
tags: | added: clientapi |
Changed in mir: | |
status: | Triaged → In Progress |
description: | updated |
description: | updated |
Changed in mir: | |
status: | In Progress → Triaged |
Changed in mir: | |
milestone: | 0.0.6 → 0.0.7 |
Changed in mir: | |
milestone: | 0.0.7 → none |
milestone: | none → 0.0.8 |
Changed in mir: | |
milestone: | 0.0.8 → 0.0.9 |
description: | updated |
description: | updated |
Changed in mir: | |
assignee: | Daniel van Vugt (vanvugt) → nobody |
Changed in mir: | |
milestone: | 0.0.9 → 0.0.10 |
Changed in mir: | |
milestone: | 0.0.10 → 0.0.11 |
Changed in mir: | |
milestone: | 0.0.11 → 0.0.13 |
Changed in mir: | |
milestone: | 0.0.13 → none |
Changed in mir: | |
assignee: | nobody → Daniel van Vugt (vanvugt) |
Changed in mir: | |
status: | Triaged → In Progress |
milestone: | none → 0.1.2 |
Changed in mir: | |
milestone: | 0.1.2 → 0.1.3 |
Changed in mir: | |
status: | In Progress → Triaged |
milestone: | 0.1.3 → none |
tags: | added: input |
Changed in mir: | |
assignee: | Daniel van Vugt (vanvugt) → nobody |
Changed in mir: | |
importance: | High → Critical |
Changed in xmir: | |
status: | New → Confirmed |
importance: | Undecided → Wishlist |
affects: | xmir → xorg-server (Ubuntu) |
tags: | added: xmir |
no longer affects: | xorg-server (Ubuntu) |
Another alternative solution would be to implement a mir_main_ loop_wait( ) type function, which blocks and provides a mutual exclusion guarantee with input callbacks.