} write;
switch_mutex_t *mutex;
+ switch_thread_rwlock_t *rwlock;
};
typedef struct http_file_context http_file_context_t;
{
register unsigned int realsize = (unsigned int) (size * nmemb);
client_t *client = data;
- int x;
+ int x, wrote = 0, sanity = 1000;
+ unsigned char *buffer = (unsigned char *) ptr;
client->bytes += realsize;
-
-
if (client->bytes > client->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) client->bytes);
client->err = 1;
return 0;
}
- x = write(client->fd, ptr, realsize);
+ do {
+ x = write(client->fd, buffer + wrote, realsize - wrote);
+ if (x > 0) {
+ wrote += x;
+ } else {
+ switch_cond_next();
+ }
+ } while (wrote != realsize && (x == -1 && (errno == EAGAIN || errno == EINTR)) && --sanity);
- if (x != (int) realsize) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write! %d out of %d\n", x, realsize);
+ if (wrote != (int) realsize) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write! fd:%d %d out of %d [%s]\n", client->fd, wrote, realsize, strerror(errno));
}
- return x;
+
+ return wrote;
}
char *dup_creds = NULL, *dynamic_url = NULL, *use_url;
char *ua = NULL;
const char *profile_name = NULL;
-
+ int tries = 10;
if (context->url_params) {
profile_name = switch_event_get_header(context->url_params, "profile_name");
return SWITCH_STATUS_FALSE;
}
+ client->fd = -1;
if (save_path) {
- if ((client->fd = open(save_path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) < 0) {
+ while(--tries && (client->fd == 0 || client->fd == -1)) {
+ client->fd = open(save_path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
+ }
+
+ if (client->fd < 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "ERROR OPENING FILE %s [%s]\n", save_path, strerror(errno));
return SWITCH_STATUS_FALSE;
}
}
if (client->fd > -1) {
close(client->fd);
+ client->fd = -1;
}
if (headers && client->headers) {
}
-static switch_status_t lock_file(http_file_context_t *context, switch_bool_t lock)
+static void lock_file(http_file_context_t *context, switch_bool_t lock)
{
-
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- http_file_context_t *xcontext = NULL;
+ void *x = NULL;
if (lock) {
- switch_mutex_lock(globals.request_mutex);
- if (!(xcontext = switch_core_hash_find(globals.request_hash, context->dest_url))) {
- switch_core_hash_insert(globals.request_hash, context->dest_url, context);
- xcontext = context;
- }
- switch_mutex_lock(context->mutex);
- switch_mutex_unlock(globals.request_mutex);
+ do {
+ switch_mutex_lock(globals.request_mutex);
+ if ((x = switch_core_hash_find(globals.request_hash, context->dest_url))) {
+ switch_mutex_unlock(globals.request_mutex);
+ switch_yield(100000);
+ }
+ } while(x);
- if (context != xcontext) {
- switch_mutex_lock(xcontext->mutex);
- switch_mutex_unlock(xcontext->mutex);
- }
-
+ switch_core_hash_insert(globals.request_hash, context->dest_url, (void *)1);
+ switch_mutex_unlock(globals.request_mutex);
} else {
switch_mutex_lock(globals.request_mutex);
- if ((xcontext = switch_core_hash_find(globals.request_hash, context->dest_url)) && xcontext == context) {
- switch_core_hash_delete(globals.request_hash, context->dest_url);
- }
- switch_mutex_unlock(context->mutex);
+ switch_core_hash_delete(globals.request_hash, context->dest_url);
switch_mutex_unlock(globals.request_mutex);
}
- return status;
+ return;
}
context = switch_core_alloc(handle->memory_pool, sizeof(*context));
context->pool = handle->memory_pool;
- switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
pdup = switch_core_strdup(context->pool, pa);
}
lock_file(context, SWITCH_TRUE);
-
- if ((status = locate_url_file(context, context->dest_url)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
+ status = locate_url_file(context, context->dest_url);
lock_file(context, SWITCH_FALSE);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ return status;
+ }
+
if ((status = switch_core_file_open(&context->fh,
context->cache_file,
handle->channels,
{
http_file_context_t *context = handle->private_info;
- switch_mutex_lock(context->mutex);
- switch_mutex_unlock(context->mutex);
-
if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
switch_core_file_close(&context->fh);
}