summaryrefslogtreecommitdiff
path: root/plugins/vfs_curl
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-12-22 21:33:28 +0100
committerGravatar waker <wakeroid@gmail.com>2010-12-22 21:33:28 +0100
commit498f4134ab8ad285cb9c0cb588f1175f7b8fdd61 (patch)
treecc43eb370ac5a322e186e9eeb37cf8ecbd117e44 /plugins/vfs_curl
parent844fdf7f5754c87175d3f11e2624e133e0358d5e (diff)
fixed vfs_curl memleak
Diffstat (limited to 'plugins/vfs_curl')
-rw-r--r--plugins/vfs_curl/vfs_curl.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c
index 9f7a6fc0..7deb1701 100644
--- a/plugins/vfs_curl/vfs_curl.c
+++ b/plugins/vfs_curl/vfs_curl.c
@@ -46,6 +46,7 @@ enum {
STATUS_FINISHED = 2,
STATUS_ABORTED = 3,
STATUS_SEEK = 4,
+ STATUS_DESTROY = 5,
};
typedef struct {
@@ -72,6 +73,8 @@ typedef struct {
int metadata_size; // size of metadata in stream
int metadata_have_size; // amount which is already in metadata buffer
+ char http_err[CURL_ERROR_SIZE];
+
// flags (bitfields to save some space)
unsigned seektoend : 1; // indicates that next tell must return length
unsigned gotheader : 1; // tells that all headers (including ICY) were processed (to start reading body)
@@ -81,8 +84,6 @@ typedef struct {
static DB_vfs_t plugin;
-static char http_err[CURL_ERROR_SIZE];
-
static int allow_new_streams;
static size_t
@@ -477,6 +478,23 @@ http_curl_control (void *stream, double dltotal, double dlnow, double ultotal, d
}
static void
+http_destroy (HTTP_FILE *fp) {
+ if (fp->content_type) {
+ free (fp->content_type);
+ }
+ if (fp->track) {
+ deadbeef->pl_item_unref (fp->track);
+ }
+ if (fp->url) {
+ free (fp->url);
+ }
+ if (fp->mutex) {
+ deadbeef->mutex_free (fp->mutex);
+ }
+ free (fp);
+}
+
+static void
http_thread_func (void *ctx) {
HTTP_FILE *fp = (HTTP_FILE *)ctx;
CURL *curl;
@@ -495,7 +513,7 @@ http_thread_func (void *ctx) {
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, http_curl_write);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, ctx);
- curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, http_err);
+ curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, fp->http_err);
curl_easy_setopt (curl, CURLOPT_BUFFERSIZE, BUFFER_SIZE/2);
curl_easy_setopt (curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, http_content_header_handler);
@@ -562,7 +580,7 @@ http_thread_func (void *ctx) {
status = curl_easy_perform (curl);
trace ("vfs_curl: curl_easy_perform retval=%d\n", status);
if (status != 0) {
- trace ("curl error:\n%s\n", http_err);
+ trace ("curl error:\n%s\n", fp->http_err);
}
deadbeef->mutex_lock (fp->mutex);
if (status == 0 && fp->length < 0 && fp->status != STATUS_ABORTED && fp->status != STATUS_SEEK) {
@@ -612,6 +630,11 @@ http_thread_func (void *ctx) {
curl_easy_cleanup (curl);
deadbeef->mutex_lock (fp->mutex);
+
+ if (fp->status == STATUS_ABORTED) {
+ http_destroy (fp);
+ return;
+ }
fp->status = STATUS_FINISHED;
deadbeef->mutex_unlock (fp->mutex);
fp->tid = 0;
@@ -621,6 +644,7 @@ static void
http_start_streamer (HTTP_FILE *fp) {
fp->mutex = deadbeef->mutex_create ();
fp->tid = deadbeef->thread_start (http_thread_func, fp);
+ deadbeef->thread_detach (fp->tid);
}
static DB_FILE *
@@ -651,24 +675,15 @@ http_close (DB_FILE *stream) {
assert (stream);
HTTP_FILE *fp = (HTTP_FILE *)stream;
- deadbeef->mutex_lock (fp->mutex);
- if (fp->tid) {
- fp->status = STATUS_ABORTED;
- trace ("http_close thread_join\n");
- deadbeef->mutex_unlock (fp->mutex);
- deadbeef->thread_join (fp->tid);
- }
- if (fp->content_type) {
- free (fp->content_type);
- }
- if (fp->track) {
- deadbeef->pl_item_unref (fp->track);
- }
- if (fp->url) {
- free (fp->url);
+ if (fp->mutex) {
+ deadbeef->mutex_lock (fp->mutex);
+ if (fp->tid) {
+ fp->status = STATUS_ABORTED;
+ deadbeef->mutex_unlock (fp->mutex);
+ return;
+ }
}
- deadbeef->mutex_free (fp->mutex);
- free (stream);
+ http_destroy (fp);
trace ("http_close done\n");
}