]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 201600 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Thu, 18 Jun 2009 15:27:10 +0000 (15:27 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 18 Jun 2009 15:27:10 +0000 (15:27 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r201600 | russell | 2009-06-18 10:24:31 -0500 (Thu, 18 Jun 2009) | 29 lines

  Fix memory corruption and leakage related reloads of non files mode MoH classes.

  For Music on Hold classes that are not files mode, meaning that we are executing
  an application that will feed us audio data, we use a thread to monitor the
  external application and read audio from it.  This thread also makes use of the
  MoH class object.  In the MoH class destructor, we used pthread_cancel() to ask
  the thread to exit.  Unfortunately, the code did not wait to ensure that the
  thread actually went away.  What needed to be done is a pthread_join() to ensure
  that the thread fully cleans up before we proceed.  By adding this one line, we
  resolve two significant problems:

    1) Since the thread was never joined, it never fully goes away.  So, on every
       reload of non-files mode MoH, an unused thread was sticking around.

    2) There was a race condition here where the application monitoring thread
       could still try to access the MoH class, even though the thread executing
       the MoH reload has already destroyed it.

  (issue #15109)
  Reported by: jvandal

  (issue #15123)
  Reported by: axisinternet

  (issue #15195)
  Reported by: amorsen

  (issue AST-208)
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@201610 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_musiconhold.c

index b50b3a8e46b0755238e87e342d3172a1b190f87c..8647316d2347f48abe190c814ab2d66e3459f76d 100644 (file)
@@ -1424,9 +1424,10 @@ static void moh_class_destructor(void *obj)
        while ((member = AST_LIST_REMOVE_HEAD(&class->members, list))) {
                free(member);
        }
-       
+
        if (class->thread) {
                pthread_cancel(class->thread);
+               pthread_join(class->thread, NULL);
                class->thread = AST_PTHREADT_NULL;
        }