summaryrefslogtreecommitdiff
path: root/libports/interrupt-operation.c
diff options
context:
space:
mode:
Diffstat (limited to 'libports/interrupt-operation.c')
-rw-r--r--libports/interrupt-operation.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/libports/interrupt-operation.c b/libports/interrupt-operation.c
index 943bd4f4..5d4b0b7a 100644
--- a/libports/interrupt-operation.c
+++ b/libports/interrupt-operation.c
@@ -27,12 +27,18 @@ kern_return_t
ports_S_interrupt_operation (struct port_info *pi,
mach_port_seqno_t seqno)
{
+ mach_port_seqno_t old;
+
if (!pi)
return EOPNOTSUPP;
- pthread_mutex_lock (&_ports_lock);
- if (pi->cancel_threshold < seqno)
- pi->cancel_threshold = seqno;
- pthread_mutex_unlock (&_ports_lock);
+
+ retry:
+ old = __atomic_load_n (&pi->cancel_threshold, __ATOMIC_SEQ_CST);
+ if (old < seqno
+ && ! __atomic_compare_exchange_n (&pi->cancel_threshold, &old, seqno,
+ 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
+ goto retry;
+
ports_interrupt_rpcs (pi);
return 0;
}