diff options
author | Lyndon Brown <jnqnfe@gmail.com> | 2018-07-05 04:54:03 +0100 |
---|---|---|
committer | Tanu Kaskinen <tanuk@iki.fi> | 2018-07-16 12:47:00 +0300 |
commit | 2d9790f566dfca73dadfbd5805c4a83401b04f25 (patch) | |
tree | ed3aa02de004229c8f2a4bb38984667830dee6f8 /src/pulse | |
parent | 613c2994af42ff08fe0a9d0e4bfce42ef781e8f6 (diff) | |
download | pulseaudio-2d9790f566dfca73dadfbd5805c4a83401b04f25.tar.gz |
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.
Diffstat (limited to 'src/pulse')
-rw-r--r-- | src/pulse/operation.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/src/pulse/operation.c b/src/pulse/operation.c index 61adf69b0..3f396f008 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; |