summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Jordan <mjordan@digium.com>2015-08-29 12:31:55 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2015-08-29 12:31:55 -0500
commit45b06a648beb8f12066e80ead0169e5fd8ecf5da (patch)
tree2d466b9081b748f06bbaeea69ef14372e0dd861c
parent545795ae0dba6fdc81d3b54e435b5fad528f5add (diff)
parenta676ba2aad5525926ae31b8317b95ae52cbbabbb (diff)
Merge "taskprocessor: Fix race condition between unreferencing and finding." into 13
-rw-r--r--main/taskprocessor.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/main/taskprocessor.c b/main/taskprocessor.c
index 20a42fab1..e8dc8f5f2 100644
--- a/main/taskprocessor.c
+++ b/main/taskprocessor.c
@@ -691,15 +691,25 @@ void *ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
return NULL;
}
+ /* To prevent another thread from finding and getting a reference to this
+ * taskprocessor we hold the singletons lock. If we didn't do this then
+ * they may acquire it and find that the listener has been shut down.
+ */
+ ao2_lock(tps_singletons);
+
if (ao2_ref(tps, -1) > 3) {
+ ao2_unlock(tps_singletons);
return NULL;
}
+
/* If we're down to 3 references, then those must be:
* 1. The reference we just got rid of
* 2. The container
* 3. The listener
*/
- ao2_unlink(tps_singletons, tps);
+ ao2_unlink_flags(tps_singletons, tps, OBJ_NOLOCK);
+ ao2_unlock(tps_singletons);
+
listener_shutdown(tps->listener);
return NULL;
}