forked from Mirrors/freeswitch
add prototype for local_stream test it and let me know what you think
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5461 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
ed0076eb18
commit
f4c1039a16
@ -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
|
||||
|
@ -125,6 +125,7 @@
|
||||
<!-- 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">
|
||||
|
@ -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"/>
|
||||
|
2
src/mod/formats/mod_local_stream/Makefile
Normal file
2
src/mod/formats/mod_local_stream/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
MODNAME=mod_native_file
|
||||
include ../../../../build/modmake.rules
|
380
src/mod/formats/mod_local_stream/mod_local_stream.c
Normal file
380
src/mod/formats/mod_local_stream/mod_local_stream.c
Normal file
@ -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:
|
||||
*/
|
213
src/mod/formats/mod_local_stream/mod_local_stream.vcproj
Normal file
213
src/mod/formats/mod_local_stream/mod_local_stream.vcproj
Normal file
@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="mod_local_stream"
|
||||
ProjectGUID="{9254C4B0-6F60-42B6-BB3A-36D63FC001C7}"
|
||||
RootNamespace="mod_local_stream"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)..\..\..\..\libs\include";"$(InputDir)..\..\..\..\libs\win32\liblocal_stream\""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""..\..\..\..\libs\liblocal_stream\Win32\$(OutDir)";"..\..\..\..\w32\vsnet\$(OutDir)""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)/mod_local_stream.lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)..\..\..\..\libs\include";"$(InputDir)..\..\..\..\libs\win32\liblocal_stream\""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""..\..\..\..\libs\liblocal_stream\Win32\$(OutDir)";"..\..\..\..\w32\vsnet\$(OutDir)""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="1"
|
||||
ImportLibrary="$(OutDir)/mod_local_stream.lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\mod_local_stream.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user