[pulseaudio-commits] src/pulse

Tanu Kaskinen tanuk at kemper.freedesktop.org
Mon Jul 16 09:48:11 UTC 2018


 src/pulse/operation.c |    3 +++
 1 file changed, 3 insertions(+)

New commits:
commit 2d9790f566dfca73dadfbd5805c4a83401b04f25
Author: Lyndon Brown <jnqnfe at gmail.com>
Date:   Thu Jul 5 04:54:03 2018 +0100

    operation: avoid state change from final state
    
    The internal operation_set_state function already returns early if the
    new state is the same as the existing state. The attached patch extends
    this to return early if already in a finalised (done/cancelled) state,
    i.e. blocks attempts to re-finalise into a different state.
    
    This helps avoid unlinking more than once (or crashing on ref count
    assertion).
    
    I was not certain whether an assertion would be a better alternative -
    with such a crash helping highlight usage problems...
    
    The situation that lead to this was the thought of someone stupidly
    trying to pa_operation_cancel() a callback within the callback
    execution itself, while designing a solution for a memory leak related
    to cancellation within my Rust binding. While no-one should do such a
    thing, if they did, they'd either trip up a ref count assertion, or the
    operation would be unlinked twice, which would be bad. It's a simple
    thing to catch and mitigate, and could prove to be a useful
    bulletproofing measure for this function in general.

diff --git a/src/pulse/operation.c b/src/pulse/operation.c
index 61adf69b..3f396f00 100644
--- a/src/pulse/operation.c
+++ b/src/pulse/operation.c
@@ -102,6 +102,9 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
     if (st == o->state)
         return;
 
+    if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED))
+        return;
+
     pa_operation_ref(o);
 
     o->state = st;



More information about the pulseaudio-commits mailing list