leak protection, better than mighty putty

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7141 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-01-08 18:35:51 +00:00
parent 4ca4a18f53
commit 9f6f77014f
5 changed files with 93 additions and 66 deletions

View File

@ -1135,12 +1135,16 @@ SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *te
\return SWITCH_STATUS_SUCCESS if the file is opened
\note the loadable module used is chosen based on the file extension
*/
SWITCH_DECLARE(switch_status_t) switch_core_file_open(_In_ switch_file_handle_t *fh,
_In_z_ const char *file_path,
_In_ uint8_t channels,
_In_ uint32_t rate,
_In_ unsigned int flags,
_In_opt_ switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
_In_ switch_file_handle_t *fh,
_In_z_ const char *file_path,
_In_ uint8_t channels,
_In_ uint32_t rate,
_In_ unsigned int flags,
_In_opt_ switch_memory_pool_t *pool);
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool) \
switch_core_perform_file_open(__FILE__, __SWITCH_FUNC__, __LINE__, _fh, _file_path, _channels, _rate, _flags, _pool)
/*!
\brief Read media from a file handle
\param fh the file handle to read from (must be initilized by you memset all 0 for read, fill in channels and rate for write)

View File

@ -301,6 +301,9 @@ struct switch_file_handle {
switch_buffer_t *buffer;
switch_byte_t *dbuf;
switch_size_t dbuflen;
const char *file;
const char *func;
int line;
};
/*! \brief Abstract interface to an asr module */

View File

@ -979,64 +979,63 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t * thread,
switch_event_fire(&event);
}
switch_core_timer_destroy(&timer);
switch_mutex_lock(conference->mutex);
conference_stop_file(conference, FILE_STOP_ASYNC);
conference_stop_file(conference, FILE_STOP_ALL);
/* Close Unused Handles */
if (conference->fnode) {
conference_file_node_t *fnode, *cur;
switch_memory_pool_t *pool;
fnode = conference->fnode;
while (fnode) {
cur = fnode;
fnode = fnode->next;
if (cur->type != NODE_TYPE_SPEECH) {
switch_core_file_close(&cur->fh);
}
pool = cur->pool;
switch_core_destroy_memory_pool(&pool);
}
conference->fnode = NULL;
}
if (conference->async_fnode) {
switch_memory_pool_t *pool;
switch_core_file_close(&conference->async_fnode->fh);
pool = conference->async_fnode->pool;
conference->async_fnode = NULL;
switch_core_destroy_memory_pool(&pool);
}
switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
switch_channel_t *channel;
if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
channel = switch_core_session_get_channel(imember->session);
/* add this little bit to preserve the bridge cause code in case of an early media call that */
/* never answers */
if (switch_test_flag(conference, CFLAG_ANSWERED)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
} else {
/* put actual cause code from outbound channel hangup here */
switch_channel_hangup(channel, conference->bridge_hangup_cause);
}
}
switch_clear_flag_locked(imember, MFLAG_RUNNING);
}
switch_mutex_unlock(conference->member_mutex);
switch_mutex_unlock(conference->mutex);
if (switch_test_flag(conference, CFLAG_DESTRUCT)) {
switch_mutex_lock(conference->mutex);
conference_stop_file(conference, FILE_STOP_ASYNC);
conference_stop_file(conference, FILE_STOP_ALL);
/* Close Unused Handles */
if (conference->fnode) {
conference_file_node_t *fnode, *cur;
switch_memory_pool_t *pool;
fnode = conference->fnode;
while (fnode) {
cur = fnode;
fnode = fnode->next;
if (cur->type != NODE_TYPE_SPEECH) {
switch_core_file_close(&cur->fh);
}
pool = cur->pool;
switch_core_destroy_memory_pool(&pool);
}
conference->fnode = NULL;
}
if (conference->async_fnode) {
switch_memory_pool_t *pool;
switch_core_file_close(&conference->async_fnode->fh);
pool = conference->async_fnode->pool;
conference->async_fnode = NULL;
switch_core_destroy_memory_pool(&pool);
}
switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
switch_channel_t *channel;
if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
channel = switch_core_session_get_channel(imember->session);
/* add this little bit to preserve the bridge cause code in case of an early media call that */
/* never answers */
if (switch_test_flag(conference, CFLAG_ANSWERED)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
} else {
/* put actual cause code from outbound channel hangup here */
switch_channel_hangup(channel, conference->bridge_hangup_cause);
}
}
switch_clear_flag_locked(imember, MFLAG_RUNNING);
}
switch_mutex_unlock(conference->member_mutex);
switch_mutex_unlock(conference->mutex);
switch_core_timer_destroy(&timer);
switch_mutex_lock(globals.hash_mutex);
switch_core_hash_delete(globals.conference_hash, conference->name);
switch_mutex_unlock(globals.hash_mutex);

View File

@ -51,6 +51,9 @@ struct local_stream_context {
switch_mutex_t *audio_mutex;
switch_buffer_t *audio_buffer;
int err;
const char *file;
const char *func;
int line;
struct local_stream_context *next;
};
typedef struct local_stream_context local_stream_context_t;
@ -191,14 +194,20 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
switch_buffer_write(audio_buffer, abuf, olen * 2);
used = switch_buffer_inuse(audio_buffer);
if (used >= source->prebuf || (source->total && used > source->samples * 2)) {
used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2);
if (source->total) {
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, dist_buf, used);
if (switch_buffer_inuse(cp->audio_buffer) > source->samples * 128) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d]\n", cp->func, cp->file, cp->line);
switch_buffer_zero(cp->audio_buffer);
} else {
switch_buffer_write(cp->audio_buffer, dist_buf, used);
}
switch_mutex_unlock(cp->audio_mutex);
}
switch_mutex_unlock(source->mutex);
@ -277,6 +286,9 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
}
context->source = source;
context->file = handle->file;
context->func = handle->func;
context->line = handle->line;
switch_mutex_lock(source->mutex);
context->next = source->context_list;

View File

@ -34,8 +34,13 @@
#include <switch.h>
#include "private/switch_core_pvt.h"
SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
const char *file_path, uint8_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
switch_file_handle_t *fh,
const char *file_path,
uint8_t channels,
uint32_t rate,
unsigned int flags,
switch_memory_pool_t *pool)
{
char *ext;
switch_status_t status;
@ -63,6 +68,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid file format [%s] for [%s]!\n", ext, file_path);
return SWITCH_STATUS_GENERR;
}
fh->file = file;
fh->func = func;
fh->line = line;
fh->flags = flags;
if (pool) {