summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-05-30 16:06:10 +0300
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-05-30 16:14:55 +0300
commit2f1a518d4572bdad2cacd8e8bc25df93acffa9b4 (patch)
tree7529956ac00a3789a4aa3310fd6c80518a6773f5 /stream
parent9b68a49d0132bbe08d3a9bf7a19276801ac415aa (diff)
parentd852b590a2aefad3c2050cf2741b4c51af8735ca (diff)
downloadmpv-2f1a518d4572bdad2cacd8e8bc25df93acffa9b4.tar.bz2
mpv-2f1a518d4572bdad2cacd8e8bc25df93acffa9b4.tar.xz
Merge svn changes up to r31211
The merged cache2.c changes are known to have problems. Will merge further fixes to them before merging this to the master branch.
Diffstat (limited to 'stream')
-rw-r--r--stream/cache2.c123
1 files changed, 78 insertions, 45 deletions
diff --git a/stream/cache2.c b/stream/cache2.c
index 7afcbf1b5b..2558adbb91 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -23,6 +23,10 @@
// TODO: seeking, data consistency checking
#define READ_USLEEP_TIME 10000
+// These defines are used to reduce the cost of many succesive
+// seeks (e.g. when a file has no index) by spinning quickly at first.
+#define INITIAL_FILL_USLEEP_TIME 1000
+#define INITIAL_FILL_USLEEP_COUNT 10
#define FILL_USLEEP_TIME 50000
#define PREFILL_SLEEP_TIME 200
#define CONTROL_SLEEP_TIME 0
@@ -49,6 +53,10 @@ static void ThreadProc( void *s );
static void *ThreadProc(void *s);
#else
#include <sys/wait.h>
+#define FORKED_CACHE 1
+#endif
+#ifndef FORKED_CACHE
+#define FORKED_CACHE 0
#endif
#include "mp_msg.h"
@@ -88,6 +96,14 @@ static int min_fill=0;
int cache_fill_status=0;
+static void cache_wakeup(stream_t *s)
+{
+#if FORKED_CACHE
+ // signal process to wake up immediately
+ kill(s->cache_pid, SIGUSR1);
+#endif
+}
+
static void cache_stats(cache_vars_t *s)
{
int newb=s->max_filepos-s->read_filepos; // new bytes in the buffer
@@ -261,13 +277,25 @@ static int cache_execute_control(cache_vars_t *s) {
return 1;
}
-static cache_vars_t* cache_init(int size,int sector){
- int num;
-#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__)
- cache_vars_t* s=shmem_alloc(sizeof(cache_vars_t));
+static void *shared_alloc(int size) {
+#if FORKED_CACHE
+ return shmem_alloc(size);
#else
- cache_vars_t* s=malloc(sizeof(cache_vars_t));
+ return malloc(size);
#endif
+}
+
+static void shared_free(void *ptr, int size) {
+#if FORKED_CACHE
+ shmem_free(ptr, size);
+#else
+ free(ptr);
+#endif
+}
+
+static cache_vars_t* cache_init(int size,int sector){
+ int num;
+ cache_vars_t* s=shared_alloc(sizeof(cache_vars_t));
if(s==NULL) return NULL;
memset(s,0,sizeof(cache_vars_t));
@@ -277,18 +305,10 @@ static cache_vars_t* cache_init(int size,int sector){
}//32kb min_size
s->buffer_size=num*sector;
s->sector_size=sector;
-#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__)
- s->buffer=shmem_alloc(s->buffer_size);
-#else
- s->buffer=malloc(s->buffer_size);
-#endif
+ s->buffer=shared_alloc(s->buffer_size);
if(s->buffer == NULL){
-#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__)
- shmem_free(s,sizeof(cache_vars_t));
-#else
- free(s);
-#endif
+ shared_free(s, sizeof(cache_vars_t));
return NULL;
}
@@ -300,7 +320,7 @@ static cache_vars_t* cache_init(int size,int sector){
void cache_uninit(stream_t *s) {
cache_vars_t* c = s->cache_data;
if(s->cache_pid) {
-#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__)
+#if !FORKED_CACHE
cache_do_control(s, -2, NULL);
#else
kill(s->cache_pid,SIGKILL);
@@ -309,16 +329,10 @@ void cache_uninit(stream_t *s) {
s->cache_pid = 0;
}
if(!c) return;
-#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__)
- free(c->buffer);
+ shared_free(c->buffer, c->buffer_size);
c->buffer = NULL;
c->stream = NULL;
- free(s->cache_data);
-#else
- shmem_free(c->buffer,c->buffer_size);
- c->buffer = NULL;
- shmem_free(s->cache_data,sizeof(cache_vars_t));
-#endif
+ shared_free(s->cache_data, sizeof(cache_vars_t));
s->cache_data = NULL;
}
@@ -327,6 +341,27 @@ static void exit_sighandler(int x){
exit(0);
}
+static void dummy_sighandler(int x) {
+}
+
+/**
+ * Main loop of the cache process or thread.
+ */
+static void cache_mainloop(cache_vars_t *s) {
+ int sleep_count = 0;
+ do {
+ if (!cache_fill(s)) {
+ if (sleep_count < INITIAL_FILL_USLEEP_COUNT) {
+ sleep_count++;
+ usec_sleep(INITIAL_FILL_USLEEP_TIME);
+ } else
+ usec_sleep(FILL_USLEEP_TIME); // idle
+ } else
+ sleep_count = 0;
+// cache_stats(s->cache_data);
+ } while (cache_execute_control(s));
+}
+
/**
* \return 1 on success, 0 if the function was interrupted and -1 on error
*/
@@ -356,7 +391,7 @@ int stream_enable_cache(stream_t *stream,int size,int min,int seek_limit){
min = s->buffer_size - s->fill_limit;
}
-#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__)
+#if FORKED_CACHE
if((stream->cache_pid=fork())){
if ((pid_t)stream->cache_pid == -1)
stream->cache_pid = 0;
@@ -404,32 +439,28 @@ err_out:
return res;
}
-#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__)
-}
-#ifdef PTHREAD_CACHE
-static void *ThreadProc( void *s ){
-#else
-static void ThreadProc( void *s ){
-#endif
+#if FORKED_CACHE
+ signal(SIGTERM,exit_sighandler); // kill
+ signal(SIGUSR1, dummy_sighandler); // wakeup
+ cache_mainloop(s);
+ // make sure forked code never leaves this function
+ exit(0);
#endif
+}
-// cache thread mainloop:
- signal(SIGTERM,exit_sighandler); // kill
- do {
- if(!cache_fill(s)){
- usec_sleep(FILL_USLEEP_TIME); // idle
- }
-// cache_stats(s->cache_data);
- } while (cache_execute_control(s));
+#if !FORKED_CACHE
#if defined(__MINGW32__) || defined(__OS2__)
+static void ThreadProc( void *s ){
+ cache_mainloop(s);
_endthread();
-#elif defined(PTHREAD_CACHE)
- return NULL;
+}
#else
- // make sure forked code never leaves this function
- exit(0);
-#endif
+static void *ThreadProc( void *s ){
+ cache_mainloop(s);
+ return NULL;
}
+#endif
+#endif
int cache_stream_fill_buffer(stream_t *s){
int len;
@@ -465,6 +496,7 @@ int cache_stream_seek_long(stream_t *stream,off_t pos){
newpos=pos/s->sector_size; newpos*=s->sector_size; // align
stream->pos=s->read_filepos=newpos;
s->eof=0; // !!!!!!!
+ cache_wakeup(stream);
cache_stream_fill_buffer(stream);
@@ -509,6 +541,7 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) {
default:
return STREAM_UNSUPPORTED;
}
+ cache_wakeup(stream);
while (s->control != -1)
usec_sleep(CONTROL_SLEEP_TIME);
switch (cmd) {