]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add prototype for local_stream test it and let me know what you think
authorAnthony Minessale <anthony.minessale@gmail.com>
Sun, 24 Jun 2007 23:09:28 +0000 (23:09 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Sun, 24 Jun 2007 23:09:28 +0000 (23:09 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5461 d0543943-73ff-0310-b7d9-9358b9ac24b2

build/modules.conf.in
conf/freeswitch.xml
conf/modules.conf.xml
src/mod/formats/mod_local_stream/Makefile [new file with mode: 0644]
src/mod/formats/mod_local_stream/mod_local_stream.c [new file with mode: 0644]
src/mod/formats/mod_local_stream/mod_local_stream.vcproj [new file with mode: 0644]
src/mod/languages/mod_mono/mod_mono.c
src/mod/timers/mod_softtimer/mod_softtimer.c
src/switch_apr.c

index c69559ec17e8cc7bbd6d4186437a3e310ec84341..a33a5bdd2e5b32fe2235bd48893226fc2dd8da1c 100644 (file)
@@ -38,6 +38,7 @@ event_handlers/mod_event_socket
 formats/mod_native_file
 formats/mod_sndfile
 #formats/mod_shout
+#formats/mod_local_stream
 #languages/mod_perl
 #languages/mod_python
 #languages/mod_spidermonkey
index eac3d9228a43a77d5b1c578299d9f79178f0ff98..82a3d7ec3f50f773de2d9a5e5aefedbf0257dd59 100644 (file)
     <!-- Say -->
     <!-- none for mod_say_en -->
     <!--#include "mod_cdr.conf.xml"-->
+    <!--#include "mod_local_stream.conf.xml"-->
   </section>
   
   <section name="dialplan" description="Regex/XML Dialplan">
index e7e2cfcc0f74fd33eda18c931595cc53803ae8ce..e78d42e39ee0cd14dd30f3f45f1b89ab8a855e81 100644 (file)
@@ -53,6 +53,8 @@
     <load module="mod_native_file"/>
     <!--For icecast/mp3 streams/files-->
     <!--<load module="mod_shout"/>-->
+    <!--For local streams (play all the files in a directory)-->
+    <!--<load module="mod_local_stream"/>-->
 
     <!-- Timers -->
     <load module="mod_softtimer"/>
diff --git a/src/mod/formats/mod_local_stream/Makefile b/src/mod/formats/mod_local_stream/Makefile
new file mode 100644 (file)
index 0000000..09018d1
--- /dev/null
@@ -0,0 +1,2 @@
+MODNAME=mod_native_file
+include ../../../../build/modmake.rules
diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c
new file mode 100644 (file)
index 0000000..f892474
--- /dev/null
@@ -0,0 +1,380 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct@yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthmct@yahoo.com>
+ *
+ *
+ * mod_local_stream.c -- Local Streaming Audio
+ *
+ */
+#include <switch.h>
+/* for apr_pstrcat */
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_local_stream_load);
+SWITCH_MODULE_DEFINITION(mod_local_stream, mod_local_stream_load, NULL, NULL);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_local_stream_shutdown);
+
+struct local_stream_source;
+
+static struct {
+       switch_mutex_t *mutex;
+       switch_hash_t *source_hash;
+} globals;
+
+static int RUNNING = 1;
+
+struct local_stream_context {
+       struct local_stream_source *source;
+       switch_mutex_t *audio_mutex;
+       switch_buffer_t *audio_buffer;
+       int err;        
+       struct local_stream_context *next;
+};
+typedef struct local_stream_context local_stream_context_t;
+
+
+struct local_stream_source {
+       char *name;
+       char *location;
+       int channels;
+       int rate;
+       int interval;
+       int samples;
+       char *timer_name;
+       local_stream_context_t *context_list;
+       switch_dir_t *dir_handle;
+       switch_mutex_t *mutex;
+       switch_memory_pool_t *pool;
+};
+typedef struct local_stream_source local_stream_source_t;
+
+static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void *obj)
+{
+       local_stream_source_t *source = obj;
+       switch_file_handle_t fh = {0};
+       local_stream_context_t *cp;
+       char file_buf[128] = "", path_buf[512] = "";
+       switch_timer_t timer = {0};
+
+
+       if (switch_core_timer_init(&timer, source->timer_name, source->interval, source->samples, source->pool) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
+               return NULL;
+       }
+
+
+       while(RUNNING) {
+               const char *fname;
+               
+               if (switch_dir_open(&source->dir_handle, source->location, source->pool) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", source->location);
+                       return NULL;
+               }
+
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "open directory: %s\n", source->location);
+               switch_yield(1000000);
+
+               while((fname = switch_dir_next_file(source->dir_handle, file_buf, sizeof(file_buf)))) {
+                       switch_size_t olen;
+                       uint8_t *abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] =  {0};
+
+                       snprintf(path_buf, sizeof(path_buf), "%s/%s", source->location, fname);
+                       fname = path_buf;
+                       if (switch_core_file_open(&fh,
+                                                                         (char *)fname,
+                                                                         source->channels,
+                                                                         source->rate,
+                                                                         SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, source->pool) != SWITCH_STATUS_SUCCESS) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", fname);
+                               switch_yield(1000000);
+                               continue;
+                       }
+                       
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Playing %s\n", fname);
+
+                       while (RUNNING) {
+                               switch_core_timer_next(&timer);
+                               olen = source->samples;
+                               if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
+                                       switch_core_file_close(&fh);
+                                       break;
+                               }
+                               
+                               switch_mutex_lock(source->mutex);
+                               for (cp = source->context_list; cp; cp = cp->next) {
+                                       switch_mutex_lock(cp->audio_mutex);
+                                       switch_buffer_write(cp->audio_buffer, abuf, olen * 2);
+                                       switch_mutex_unlock(cp->audio_mutex);
+                               }
+                               switch_mutex_unlock(source->mutex);
+                       }
+
+               }
+
+               switch_dir_close(source->dir_handle);
+
+       }
+       
+       switch_core_destroy_memory_pool(&source->pool);
+
+       return NULL;
+}
+
+static switch_status_t local_stream_file_open(switch_file_handle_t *handle, char *path)
+{
+       local_stream_context_t *context;
+       local_stream_source_t *source;
+       
+       if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
+               return SWITCH_STATUS_FALSE;
+       }
+       
+       switch_mutex_lock(globals.mutex);
+       source = switch_core_hash_find(globals.source_hash, path);
+       switch_mutex_unlock(globals.mutex);
+
+       if (!source) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unknown source %s\n", path);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
+               return SWITCH_STATUS_MEMERR;
+       }       
+
+       handle->samples = 0;
+       handle->samplerate = source->rate;
+       handle->channels = source->channels;
+       handle->format = 0;
+       handle->sections = 0;
+       handle->seekable = 0;
+       handle->speed = 0;
+       handle->private_info = context;
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening Stream [%s] %dhz\n", path, handle->samplerate);
+       
+       switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
+       if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+               return SWITCH_STATUS_MEMERR;
+       }       
+       
+       context->source = source;
+
+       switch_mutex_lock(source->mutex);
+       context->next = source->context_list;
+       source->context_list = context;
+       switch_mutex_unlock(source->mutex);
+
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
+{
+       local_stream_context_t *cp, *last = NULL, *context = handle->private_info;
+
+       switch_mutex_lock(context->source->mutex);
+       for (cp = context->source->context_list; cp; cp = cp->next) {
+               if (cp == context) {
+                       if (last) {
+                               last->next = cp->next;
+                       } else {
+                               context->source->context_list = cp->next;
+                       }
+                       break;
+               }
+               last = cp;
+       }
+       switch_mutex_unlock(context->source->mutex);
+       switch_buffer_destroy(&context->audio_buffer);
+       
+       return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t local_stream_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence)
+{
+       return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t local_stream_file_read(switch_file_handle_t *handle, void *data, size_t *len)
+{
+       local_stream_context_t *context = handle->private_info;
+       switch_size_t bytes = 0;
+       size_t need = *len * 2;
+
+       switch_mutex_lock(context->audio_mutex);
+       if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) {
+               *len = bytes / 2;
+       } else {
+               if (need > 2560) {
+                       need = 2560;
+               }
+               memset(data, 255, need);
+               *len = need / 2;
+       }
+       switch_mutex_unlock(context->audio_mutex);
+       return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t local_stream_file_write(switch_file_handle_t *handle, void *data, size_t *len)
+{
+       return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t local_stream_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
+{
+       return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t local_stream_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string)
+{
+       return SWITCH_STATUS_FALSE;
+}
+
+/* Registration */
+
+static char *supported_formats[SWITCH_MAX_CODECS] = { 0 };
+
+static void launch_threads(void)
+{
+       char *cf = "local_stream.conf";
+       switch_xml_t cfg, xml, directory, param;
+       switch_memory_pool_t *pool;
+       local_stream_source_t *source;
+       switch_thread_t *thread;
+       switch_threadattr_t *thd_attr = NULL;
+
+
+       if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
+               return;
+       }
+
+       for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) {
+               char *path = (char *) switch_xml_attr(directory, "path");
+               char *name = (char *) switch_xml_attr(directory, "name");
+               
+               if (!(name && path)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid config!\n");
+                       continue;
+               }
+
+               if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
+                       abort();
+               }
+
+               source = switch_core_alloc(pool, sizeof(*source));
+               assert(source != NULL);
+               source->pool = pool;
+               
+               source->name = switch_core_strdup(source->pool, name);
+               source->location = switch_core_strdup(source->pool, path);
+               source->rate = 8000;
+               source->interval = 20;
+               source->channels = 1;
+               source->timer_name = "soft";
+
+               
+               for (param = switch_xml_child(directory, "param"); param; param = param->next) {
+                       char *var = (char *) switch_xml_attr_soft(param, "name");
+                       char *val = (char *) switch_xml_attr_soft(param, "value");
+
+                       if (!strcasecmp(var, "rate")) {
+                               int tmp = atoi(val);
+                               if (tmp == 8000 || tmp == 16000) {
+                                       source->rate = tmp;
+                               }
+                       } else if (!strcasecmp(var, "channels")) {
+                               int tmp = atoi(val);
+                               if (tmp == 1 || tmp == 2) {
+                                       source->channels = tmp;
+                               }
+                       } else if (!strcasecmp(var, "interval")) {
+                               source->interval = atoi(val);
+                       } else if (!strcasecmp(var, "timer_name")) {
+                               source->timer_name = switch_core_strdup(source->pool, val);
+                       }
+               }
+               
+               source->samples = switch_bytes_per_frame(source->rate, source->interval);
+               switch_core_hash_insert(globals.source_hash, source->name, source);
+               
+               switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool);
+               
+               switch_threadattr_create(&thd_attr, source->pool);
+               switch_threadattr_detach_set(thd_attr, 1);
+               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+               switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool);
+               
+       }
+}
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_local_stream_load)
+{
+       switch_file_interface_t *file_interface;
+       supported_formats[0] = "local_stream";
+       
+       *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+       file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
+       file_interface->interface_name = modname;
+       file_interface->extens = supported_formats;
+       file_interface->file_open = local_stream_file_open;
+       file_interface->file_close = local_stream_file_close;
+       file_interface->file_read = local_stream_file_read;
+       file_interface->file_write = local_stream_file_write;
+       file_interface->file_seek = local_stream_file_seek;
+       file_interface->file_set_string = local_stream_file_set_string;
+       file_interface->file_get_string = local_stream_file_get_string;
+
+       memset(&globals, 0, sizeof(globals));
+       switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, pool);
+       switch_core_hash_init(&globals.source_hash, pool);
+       launch_threads();
+       
+       /* indicate that the module should continue to be loaded */
+       return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_local_stream_shutdown)
+{
+       RUNNING = 0;
+       switch_yield(500000);
+       return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */
diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.vcproj b/src/mod/formats/mod_local_stream/mod_local_stream.vcproj
new file mode 100644 (file)
index 0000000..30776e9
--- /dev/null
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="mod_local_stream"\r
+       ProjectGUID="{9254C4B0-6F60-42B6-BB3A-36D63FC001C7}"\r
+       RootNamespace="mod_local_stream"\r
+       Keyword="Win32Proj"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;;&quot;$(InputDir)..\..\..\..\libs\win32\liblocal_stream\&quot;"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               WarnAsError="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories="&quot;..\..\..\..\libs\liblocal_stream\Win32\$(OutDir)&quot;;&quot;..\..\..\..\w32\vsnet\$(OutDir)&quot;"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"\r
+                               SubSystem="2"\r
+                               ImportLibrary="$(OutDir)/mod_local_stream.lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;;&quot;$(InputDir)..\..\..\..\libs\win32\liblocal_stream\&quot;"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
+                               RuntimeLibrary="2"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               WarnAsError="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories="&quot;..\..\..\..\libs\liblocal_stream\Win32\$(OutDir)&quot;;&quot;..\..\..\..\w32\vsnet\$(OutDir)&quot;"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               LinkTimeCodeGeneration="1"\r
+                               ImportLibrary="$(OutDir)/mod_local_stream.lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\mod_local_stream.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
index cfc7d8fb295c0ef07cdafc8f9619089e17378638..95943320dc1726a207beb4f765f630ae27b4efad 100755 (executable)
@@ -194,12 +194,13 @@ switch_status_t mod_mono_load_modules(const char *module_dir)
        iter = NULL;
        mono_plugin *plugin = NULL;
     const char *fname = NULL;
+    char buf[512] = "";
 
        if (switch_dir_open(&module_dir_handle, module_dir, mono_pool) != SWITCH_STATUS_SUCCESS)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not open directory: %s\n", module_dir);
 
        /* Read the modules directory */
-       while ((fname = switch_dir_next_file(module_dir_handle))) {
+       while ((fname = switch_dir_next_file(module_dir_handle, buf, sizeof(buf)))) {
                assembly = (MonoAssembly *) switch_core_alloc(mono_pool, sizeof(assembly));
                image = (MonoImage *) switch_core_alloc(mono_pool, sizeof(image));
 
index 35e817eb4d7fd14d989179ccde243a5a74e8fc7d..0f7cdb59c2acce911d4a29695cc8f1e6664f7776 100644 (file)
@@ -43,6 +43,7 @@ static switch_memory_pool_t *module_pool = NULL;
 
 static struct {
        int32_t RUNNING;
+       int32_t STARTED;
        switch_mutex_t *mutex;
 } globals;
 
@@ -76,6 +77,14 @@ static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
 static inline switch_status_t timer_init(switch_timer_t *timer)
 {
        timer_private_t *private_info;
+       int sanity = 0;
+
+       while(globals.STARTED == 0) {
+               switch_yield(100000);
+               if (++sanity == 10) {
+                       break;
+               }
+       }
 
        if (globals.RUNNING != 1 || !globals.mutex) {
                return SWITCH_STATUS_FALSE;
@@ -220,9 +229,9 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_softtimer_runtime)
 
        memset(&globals, 0, sizeof(globals));
        switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
-
-       globals.RUNNING = 1;
-
+       
+       globals.STARTED = globals.RUNNING = 1;
+       
        while (globals.RUNNING == 1) {
                reference += STEP_MIC;
 
index 564818581650754ba48324d609267ac5c2ffd0fe..069884fc06b1cfea55183c6fe247099c2d2b3dc5 100644 (file)
@@ -391,26 +391,46 @@ struct switch_dir {
 SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t **new_dir, const char *dirname, switch_memory_pool_t *pool)
 {
        switch_status_t status;
-       switch_dir_t *dir = switch_core_alloc(pool, sizeof(switch_dir_t));
-       status = apr_dir_open(&(dir->dir_handle), dirname, pool);
-       *new_dir = dir;
+       switch_dir_t *dir = malloc(sizeof(*dir));
+
+       memset(dir, 0, sizeof(*dir));
+       if ((status = apr_dir_open(&(dir->dir_handle), dirname, pool)) == APR_SUCCESS) {
+               *new_dir = dir;
+       } else {
+               free(dir);
+               *new_dir = NULL;
+       }
+
        return status;   
 }
 
 SWITCH_DECLARE(switch_status_t) switch_dir_close(switch_dir_t *thedir)
 {
        return apr_dir_close(thedir->dir_handle);
+
+       free(thedir);
 }
 
 SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *buf, switch_size_t len) 
 {
        const char *fname = NULL;
        apr_int32_t finfo_flags = APR_FINFO_DIRENT | APR_FINFO_TYPE | APR_FINFO_NAME;
+       const char *name;
+       
        while (apr_dir_read(&(thedir->finfo), finfo_flags, thedir->dir_handle) == SWITCH_STATUS_SUCCESS) {
-               if (thedir->finfo.filetype != APR_REG)
+               if (thedir->finfo.filetype != APR_REG) {
                        continue;
-               if (thedir->finfo.fname) {
-                       switch_copy_string(buf, thedir->finfo.fname, len);
+               }
+               if (!(name = thedir->finfo.fname)) {
+                       name = thedir->finfo.name;
+               }
+               
+               if (!name) {
+                       continue;
+               }
+
+               if (name) {
+                       switch_copy_string(buf, name, len);
                        fname = buf;
                } else {
                        continue;