diff options
author | Matt Jordan <mjordan@digium.com> | 2015-08-29 12:31:55 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2015-08-29 12:31:55 -0500 |
commit | 45b06a648beb8f12066e80ead0169e5fd8ecf5da (patch) | |
tree | 2d466b9081b748f06bbaeea69ef14372e0dd861c | |
parent | 545795ae0dba6fdc81d3b54e435b5fad528f5add (diff) | |
parent | a676ba2aad5525926ae31b8317b95ae52cbbabbb (diff) |
Merge "taskprocessor: Fix race condition between unreferencing and finding." into 13
-rw-r--r-- | main/taskprocessor.c | 12 |
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; } |