From: Rémi Bernon rbernon@codeweavers.com
The client should check that the lower SEQUENCE_MASK_BITS are zero before reading the data and confirm that the number is unchanged when it's finished.
Based on a patch by Huw Davies huw@codeweavers.com. --- server/protocol.def | 1 + server/queue.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
diff --git a/server/protocol.def b/server/protocol.def index f8216d57e25..e7c267b4148 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -899,6 +899,7 @@ struct shared_cursor
struct desktop_shared_memory { + unsigned int seq; /* sequence number - server updating if (seq & 1) != 0 */ struct shared_cursor cursor; /* global cursor information */ }; typedef volatile struct desktop_shared_memory desktop_shm_t; diff --git a/server/queue.c b/server/queue.c index d9a7cd2be2c..3750c849073 100644 --- a/server/queue.c +++ b/server/queue.c @@ -232,14 +232,24 @@ static unsigned int last_input_time; static cursor_pos_t cursor_history[64]; static unsigned int cursor_history_latest;
+#if defined(__i386__) || defined(__x86_64__) +#define __SHARED_WRITE_FENCE( x ) ++(x) +#else +#define __SHARED_WRITE_FENCE( x ) __atomic_add_fetch( &(x), 1, __ATOMIC_RELEASE ) +#endif + #define SHARED_WRITE_BEGIN( object, type ) \ do { \ const type *__shared = (object)->shared; \ type *shared = (type *)__shared; \ + unsigned int __seq = __SHARED_WRITE_FENCE( shared->seq ); \ + assert( (__seq & 1) != 0 ); \ do
#define SHARED_WRITE_END \ while(0); \ + __seq = __SHARED_WRITE_FENCE( shared->seq ); \ + assert( (__seq & 1) == 0 ); \ } while(0);
static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue );