[svn-commits] trunk r31953 - /trunk/res/res_musiconhold.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Jun 3 23:21:43 MST 2006


Author: russell
Date: Sun Jun  4 01:21:43 2006
New Revision: 31953

URL: http://svn.digium.com/view/asterisk?rev=31953&view=rev
Log:
Use a dynamically sized array to store the list of files for moh "files" mode
 - Instead of always allocating 64KB of memory for every MOH class, this has
   been reduced to only a single pointer per class, with more memory only
   allocatted when using "files" mode, as needed
 - Instead of imposing a length limit on the full filename, including full
   path, of 127 characters, use PATH_MAX, the maximum length that the system
   can handle
 - There is no longer a limit on the number of files than can be used for a
   single MOH class using "files" mode

Modified:
    trunk/res/res_musiconhold.c

Modified: trunk/res/res_musiconhold.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_musiconhold.c?rev=31953&r1=31952&r2=31953&view=diff
==============================================================================
--- trunk/res/res_musiconhold.c (original)
+++ trunk/res/res_musiconhold.c Sun Jun  4 01:21:43 2006
@@ -72,8 +72,7 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/linkedlists.h"
 
-#define MAX_MOHFILES 512
-#define MAX_MOHFILE_LEN 128
+#define INITIAL_NUM_FILES   8
 
 static char *app0 = "MusicOnHold";
 static char *app1 = "WaitMusicOnHold";
@@ -133,17 +132,22 @@
 	char dir[256];
 	char args[256];
 	char mode[80];
-	/* XXX This means that we are allocating 64KB of memory for every musiconhold class XXX */
-	char filearray[MAX_MOHFILES][MAX_MOHFILE_LEN];
+	/*! A dynamically sized array to hold the list of filenames in "files" mode */
+	char **filearray;
+	/*! The current size of the filearray */
+	int allowed_files;
+	/*! The current number of files loaded into the filearray */
+	int total_files;
 	unsigned int flags;
-	int total_files;
+	/*! The format from the MOH source, not applicable to "files" mode */
 	int format;
-	int pid;		/* PID of mpg123 */
+	/*! The pid of the external application delivering MOH */
+	int pid;
 	time_t start;
 	pthread_t thread;
-	/* Source of audio */
+	/*! Source of audio */
 	int srcfd;
-	/* FD for timing source */
+	/*! FD for timing source */
 	int pseudofd;
 	AST_LIST_HEAD_NOLOCK(, mohdata) members;
 	AST_LIST_ENTRY(mohclass) list;
@@ -164,20 +168,28 @@
 #define MAX_MP3S 256
 
 
-static void ast_moh_free_class(struct mohclass **class) 
+static void ast_moh_free_class(struct mohclass **mohclass) 
 {
 	struct mohdata *member;
-	
-	while ((member = AST_LIST_REMOVE_HEAD(&((*class)->members), list)))
+	struct mohclass *class = *mohclass;
+	int i;
+	
+	while ((member = AST_LIST_REMOVE_HEAD(&class->members, list)))
 		free(member);
 	
-	if ((*class)->thread) {
-		pthread_cancel((*class)->thread);
-		(*class)->thread = 0;
-	}
-
-	free(*class);
-	*class = NULL;
+	if (class->thread) {
+		pthread_cancel(class->thread);
+		class->thread = 0;
+	}
+
+	if (class->filearray) {
+		for (i = 0; i < class->total_files; i++)
+			free(class->filearray[i]);
+		free(class->filearray);
+	}
+
+	free(class);
+	*mohclass = NULL;
 }
 
 
@@ -402,14 +414,6 @@
 		ast_log(LOG_WARNING, "Pipe failed\n");
 		return -1;
 	}
-#if 0
-	printf("%d files total, %d args total\n", files, argc);
-	{
-		int x;
-		for (x=0;argv[x];x++)
-			printf("arg%d: %s\n", x, argv[x]);
-	}
-#endif	
 	if (!files) {
 		ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir);
 		close(fds[0]);
@@ -721,12 +725,35 @@
 	generate: moh_generate,
 };
 
+static int moh_add_file(struct mohclass *class, const char *filepath)
+{
+	if (!class->allowed_files) {
+		if (!(class->filearray = ast_calloc(1, INITIAL_NUM_FILES * sizeof(*class->filearray))))
+			return -1;
+		class->allowed_files = INITIAL_NUM_FILES;
+	} else if (class->total_files == class->allowed_files) {
+		if (!(class->filearray = ast_realloc(class->filearray, class->allowed_files * sizeof(*class->filearray) * 2))) {
+			class->allowed_files = 0;
+			class->total_files = 0;
+			return -1;
+		}
+		class->allowed_files *= 2;
+	}
+
+	if (!(class->filearray[class->total_files] = ast_strdup(filepath)))
+		return -1;
+
+	class->total_files++;
+
+	return 0;
+}
+
 static int moh_scan_files(struct mohclass *class) {
 
 	DIR *files_DIR;
 	struct dirent *files_dirent;
 	char path[512];
-	char filepath[MAX_MOHFILE_LEN];
+	char filepath[PATH_MAX];
 	char *ext;
 	struct stat statbuf;
 	int dirnamelen;
@@ -738,16 +765,19 @@
 		return -1;
 	}
 
+	for (i = 0; i < class->total_files; i++)
+		free(class->filearray[i]);
+
 	class->total_files = 0;
 	dirnamelen = strlen(class->dir) + 2;
 	getcwd(path, 512);
 	chdir(class->dir);
-	memset(class->filearray, 0, MAX_MOHFILES*MAX_MOHFILE_LEN);
 	while ((files_dirent = readdir(files_DIR))) {
-		if ((strlen(files_dirent->d_name) < 4) || ((strlen(files_dirent->d_name) + dirnamelen) >= MAX_MOHFILE_LEN))
+		/* The file name must be at least long enough to have the file type extension */
+		if ((strlen(files_dirent->d_name) < 4))
 			continue;
 
-		snprintf(filepath, MAX_MOHFILE_LEN, "%s/%s", class->dir, files_dirent->d_name);
+		snprintf(filepath, sizeof(filepath), "%s/%s", class->dir, files_dirent->d_name);
 
 		if (stat(filepath, &statbuf))
 			continue;
@@ -765,13 +795,10 @@
 			if (!strcmp(filepath, class->filearray[i]))
 				break;
 
-		if (i == class->total_files)
-			strcpy(class->filearray[class->total_files++], filepath);
-
-		/* If the new total files is equal to the maximum allowed, stop adding new ones */
-		if (class->total_files == MAX_MOHFILES)
-			break;
-
+		if (i == class->total_files) {
+			if (moh_add_file(class, filepath))
+				break;
+		}
 	}
 
 	closedir(files_DIR);



More information about the svn-commits mailing list