summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-09 18:21:32 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-09 18:21:32 +0100
commitd681406df76cc5dc07748ff36bc39226fec4219a (patch)
tree285e2fde9aa405ee7e7aac2127ac2cbff861078c /plugins
parentfea833857e9e044e88679f21a32befa58f9305a1 (diff)
parent0217ea3d83980f45a6ae8a4776021df07b1abcaf (diff)
Merge branch 'vfs'
Diffstat (limited to 'plugins')
-rw-r--r--plugins/vfs_curl/vfs_curl.c96
1 files changed, 44 insertions, 52 deletions
diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c
index 3185df67..1ef633b1 100644
--- a/plugins/vfs_curl/vfs_curl.c
+++ b/plugins/vfs_curl/vfs_curl.c
@@ -24,8 +24,8 @@
#include <curl/curlver.h>
#include "../../deadbeef.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -70,6 +70,9 @@ static DB_vfs_t plugin;
static char http_err[CURL_ERROR_SIZE];
+static int vfs_curl_abort;
+static int vfs_curl_count;
+
static size_t
http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream);
@@ -190,26 +193,6 @@ http_curl_write (void *ptr, size_t size, size_t nmemb, void *stream) {
return nmemb * size - avail;
}
-#if 0
-static size_t
-http_size_header_handler (void *ptr, size_t size, size_t nmemb, void *stream) {
- assert (stream);
- HTTP_FILE *fp = (HTTP_FILE *)stream;
- // don't copy/allocate mem, just grep for "Content-Length: "
- const char *cl = strcasestr (ptr, "Content-Length:");
- if (cl) {
- cl += 15;
- while (*cl <= 0x20) {
- cl++;
- }
- fp->length = atoi (cl);
- trace ("vfs_curl: file size is %d bytes\n", fp->length);
- return 0;
- }
- return size * nmemb;
-}
-#endif
-
static const uint8_t *
parse_header (const uint8_t *p, const uint8_t *e, uint8_t *key, int keysize, uint8_t *value, int valuesize) {
int sz; // will hold lenght of extracted string
@@ -313,25 +296,25 @@ http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream)
return size * nmemb;
}
-//static size_t
-//http_curl_write_abort (void *ptr, size_t size, size_t nmemb, void *stream) {
-// return 0;
-//}
-
static int
http_curl_control (void *stream, double dltotal, double dlnow, double ultotal, double ulnow) {
-// trace ("http_curl_control\n");
- assert (stream);
HTTP_FILE *fp = (HTTP_FILE *)stream;
+ trace ("http_curl_control, status = %d\n", fp ? fp->status : -1);
+ assert (stream);
if (fp->status == STATUS_ABORTED) {
trace ("vfs_curl STATUS_ABORTED in progress callback\n");
return -1;
}
+ if (vfs_curl_abort) {
+ trace ("vfs_curl: aborting stream %p due to external request\n");
+ return -1;
+ }
return 0;
}
static void
http_thread_func (void *ctx) {
+ vfs_curl_count++;
HTTP_FILE *fp = (HTTP_FILE *)ctx;
CURL *curl;
curl = curl_easy_init ();
@@ -339,26 +322,6 @@ http_thread_func (void *ctx) {
fp->status = STATUS_INITIAL;
int status;
-#if 0
- // get filesize (once)
- curl_easy_setopt (curl, CURLOPT_URL, fp->url);
- curl_easy_setopt (curl, CURLOPT_NOBODY, 0);
- curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 10);
- curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, http_size_header_handler);
- curl_easy_setopt (curl, CURLOPT_HEADERDATA, ctx);
- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, http_curl_write_abort);
- curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, http_curl_control);
- curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 10);
- status = curl_easy_perform(curl);
-#if 0
- if (status != 0) {
- trace ("vfs_curl: curl_easy_perform failed while getting filesize, status %d\n", status);
- }
-#endif
-#endif
-// fp->status = STATUS_STARTING;
trace ("vfs_curl: started loading data\n");
for (;;) {
@@ -436,6 +399,7 @@ http_thread_func (void *ctx) {
fp->status = STATUS_FINISHED;
deadbeef->mutex_unlock (fp->mutex);
fp->tid = 0;
+ vfs_curl_count--;
}
static void
@@ -497,7 +461,7 @@ http_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
while (fp->status != STATUS_FINISHED && sz > 0)
{
// wait until data is available
- while ((fp->remaining == 0 || fp->skipbytes > 0) && fp->status != STATUS_FINISHED) {
+ while ((fp->remaining == 0 || fp->skipbytes > 0) && fp->status != STATUS_FINISHED && !vfs_curl_abort) {
deadbeef->mutex_lock (fp->mutex);
int skip = min (fp->remaining, fp->skipbytes);
if (skip > 0) {
@@ -651,7 +615,7 @@ http_get_content_type (DB_FILE *stream) {
http_start_streamer (fp);
}
trace ("http_get_content_type waiting for response...\n");
- while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader) {
+ while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader && !vfs_curl_abort) {
usleep (3000);
}
return fp->content_type;
@@ -672,7 +636,7 @@ http_get_content_name (DB_FILE *stream) {
http_start_streamer (fp);
}
trace ("http_get_content_name waiting for response...\n");
- while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader) {
+ while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader && !vfs_curl_abort) {
usleep (3000);
}
return fp->content_name;
@@ -709,6 +673,32 @@ http_stop (DB_FILE *stream) {
fp->status = STATUS_ABORTED;
}
+static int
+vfs_curl_on_abort (DB_event_t *ev, uintptr_t data) {
+ trace ("vfs_curl: got abort signal!\n");
+ if (vfs_curl_count > 0) {
+ vfs_curl_abort = 1;
+ while (vfs_curl_count > 0) {
+ usleep (20000);
+ }
+ vfs_curl_abort = 0;
+ }
+ return 0;
+}
+
+static int
+vfs_curl_start (void) {
+ deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_ABORTREAD, DB_CALLBACK (vfs_curl_on_abort), 0);
+ return 0;
+}
+
+static int
+vfs_curl_stop (void) {
+ deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_ABORTREAD, DB_CALLBACK (vfs_curl_on_abort), 0);
+ vfs_curl_on_abort (NULL, 0);
+ return 0;
+}
+
static const char *scheme_names[] = { "http://", "ftp://", NULL };
// standard stdio vfs
@@ -722,6 +712,8 @@ static DB_vfs_t plugin = {
.plugin.author = "Alexey Yakovenko",
.plugin.email = "waker@users.sourceforge.net",
.plugin.website = "http://deadbeef.sf.net",
+ .plugin.start = vfs_curl_start,
+ .plugin.stop = vfs_curl_stop,
.open = http_open,
.close = http_close,
.read = http_read,