aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-06-16 17:37:38 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-06-16 17:37:38 +0000
commitf6b54c606b49eb12b383d604ac35af42ad8ca3c4 (patch)
tree9998626aa643a32e85ba354a75b4b8adedcded4d /channels/chan_iax2.c
parent1ed14e26cfdab474d28d177db9ab762a4ecf07e6 (diff)
Merged revisions 270867 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r270867 | dvossel | 2010-06-16 12:36:51 -0500 (Wed, 16 Jun 2010) | 28 lines Merged revisions 270866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r270866 | dvossel | 2010-06-16 12:35:29 -0500 (Wed, 16 Jun 2010) | 22 lines fixes chan_iax2 race condition There is code in chan_iax2.c that attempts to guarantee that only a single active thread will handle a call number at a time. This code works once the thread is added to an active_list of threads, but we are not currently guaranteed that a newly activated thread will enter the active_list immediately because it is left up to the thread to add itself after frames have been queued to it. This means that if two frames come in for the same call number at the same time, it is possible for them to grab two separate threads because the first thread did not add itself to the active_list fast enough. This causes some pretty complex problems. This patch resolves this race condition by immediately adding an activated thread to the active_list within the network thread and only depending on the thread to remove itself once it is done processing the frames queued to it. By doing this we are guaranteed that if another frame for the same call number comes in at the same time, that this thread will immediately be found in the active_list of threads. Review: https://reviewboard.asterisk.org/r/720/ ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@270868 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 3cf2596fb..6fc1b6580 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -9252,6 +9252,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
thread->ffinfo.type = fh->type;
thread->ffinfo.csub = fh->csub;
+ AST_LIST_INSERT_HEAD(&active_list, thread, list);
}
AST_LIST_UNLOCK(&active_list);
}
@@ -11215,11 +11216,6 @@ static void *iax2_process_thread(void *data)
if (thread->iostate == IAX_IOSTATE_IDLE)
continue;
- /* Add ourselves to the active list now */
- AST_LIST_LOCK(&active_list);
- AST_LIST_INSERT_HEAD(&active_list, thread, list);
- AST_LIST_UNLOCK(&active_list);
-
/* See what we need to do */
switch(thread->iostate) {
case IAX_IOSTATE_READY:
@@ -11243,7 +11239,9 @@ static void *iax2_process_thread(void *data)
thread->curfunc[0]='\0';
#endif
- /* Now... remove ourselves from the active list, and return to the idle list */
+ /* The network thread added us to the active_thread list when we were given
+ * frames to process, Now that we are done, we must remove ourselves from
+ * the active list, and return to the idle list */
AST_LIST_LOCK(&active_list);
AST_LIST_REMOVE(&active_list, thread, list);
AST_LIST_UNLOCK(&active_list);