diff options
| -rw-r--r-- | ChangeLog | 18 | ||||
| -rw-r--r-- | fm.h | 4 | ||||
| -rw-r--r-- | image.c | 227 | 
3 files changed, 167 insertions, 82 deletions
| @@ -1,5 +1,21 @@  2002-02-03  Hironori Sakamoto <hsaka@mth.biglobe.ne.jp> +	* [w3m-dev 02967] parallel image downloading +	* fm.h (ImageCache): add touch, pid +	* image.c (getCharSize): retry fscanf +	* image.c (drawImage): retry fflush +	* image.c (MAX_LOAD_IMAGE): added, default 4 +	* image.c (image_cache): change to ImageCache** +	* image.c (image_lock): added +	* image.c (load_image_handler): signal SIGUSR1 +	* image.c (load_image_next): signal SIGUSR1 +	* image.c (loadImage): parallel image downloading +	* image.c (getImage): initialize touch, pid +	* image.c (getImageSize): return value is TRUE or FALSE +			retry fscanf + +2002-02-03  Hironori Sakamoto <hsaka@mth.biglobe.ne.jp> +  	* [w3m-dev 02970] multiple -lnsl -lsocket  	* configure: merge bsdlib and extlib detection, use extlib only  		add ldflags to extlib @@ -2729,4 +2745,4 @@  	* release-0-2-1  	* import w3m-0.2.1 -$Id: ChangeLog,v 1.293 2002/02/03 06:23:37 ukai Exp $ +$Id: ChangeLog,v 1.294 2002/02/03 06:38:49 ukai Exp $ @@ -1,4 +1,4 @@ -/* $Id: fm.h,v 1.47 2002/02/03 06:12:41 ukai Exp $ */ +/* $Id: fm.h,v 1.48 2002/02/03 06:38:49 ukai Exp $ */  /*    * w3m: WWW wo Miru utility   *  @@ -325,6 +325,8 @@ typedef struct _imageCache {      char *url;      ParsedURL *current;      char *file; +    char *touch; +    pid_t pid;      char loaded;      int index;      short width; @@ -1,4 +1,4 @@ -/* $Id: image.c,v 1.2 2002/01/31 18:28:24 ukai Exp $ */ +/* $Id: image.c,v 1.3 2002/02/03 06:38:49 ukai Exp $ */  #include "fm.h"  #include <sys/types.h> @@ -57,8 +57,12 @@ getCharSize()      f = popen(tmp->ptr, "r");      if (!f)  	return FALSE; -    fscanf(f, "%d %d", &w, &h); +    while (fscanf(f, "%d %d", &w, &h) < 0) { +	if (feof(f)) +	    break; +    }      pclose(f); +      if (!(w > 0 && h > 0))  	return FALSE;      if (!set_pixel_per_char) @@ -212,14 +216,9 @@ drawImage()  	fputs(i->cache->file, Imgdisplay_wf);  	fputs("\n", Imgdisplay_wf);  	fputs("4;\n", Imgdisplay_wf);	/* put '\n' */ -      again: -	if (fflush(Imgdisplay_wf) != 0) { -	    switch (errno) { -	    case EINTR: -		goto again; -	    default: +	while (fflush(Imgdisplay_wf) != 0) { +	    if (ferror(Imgdisplay_wf))  		goto err; -	    }  	}  	if (!fgetc(Imgdisplay_rf))  	    goto err; @@ -228,14 +227,9 @@ drawImage()  	return;      fputs("3;\n", Imgdisplay_wf);	/* XSync() */      fputs("4;\n", Imgdisplay_wf);	/* put '\n' */ -  again2: -    if (fflush(Imgdisplay_wf) != 0) { -	switch (errno) { -	case EINTR: -	    goto again2; -	default: +    while (fflush(Imgdisplay_wf) != 0) { +	if (ferror(Imgdisplay_wf))  	    goto err; -	}      }      if (!fgetc(Imgdisplay_rf))  	goto err; @@ -269,17 +263,22 @@ clearImage()  /* load image */ +#ifndef MAX_LOAD_IMAGE +#define MAX_LOAD_IMAGE 4 +#endif +static int max_load_image = MAX_LOAD_IMAGE;  static Hash_sv *image_hash = NULL;  static Hash_sv *image_file = NULL;  static GeneralList *image_list = NULL; -static ImageCache *image_cache = NULL; -static pid_t image_pid = 0; +static ImageCache **image_cache = NULL; +static char *image_lock = NULL;  static int need_load_image = FALSE;  static MySignalHandler  load_image_handler(SIGNAL_ARG)  {      need_load_image = TRUE; +    signal(SIGUSR1, load_image_handler);      SIGNAL_RETURN;  } @@ -287,6 +286,7 @@ static MySignalHandler  load_image_next(SIGNAL_ARG)  {      need_load_image = TRUE; +    signal(SIGUSR1, load_image_handler);      loadImage(IMG_FLAG_NEXT);      SIGNAL_RETURN;  } @@ -335,89 +335,150 @@ getAllImage(Buffer *buf)  void  loadImage(int flag)  { -    int wait_st; +    ImageCache *cache; +    struct stat st; +    int wait_st, i; +    if (!image_cache) { +	image_cache = New_N(ImageCache *, max_load_image); +	bzero(image_cache, sizeof(ImageCache *) * max_load_image); +    }      if (flag == IMG_FLAG_STOP) { -	if (image_pid) { -	    kill(image_pid, SIGKILL); +	for (i = 0; i < max_load_image; i++) { +	    cache = image_cache[i]; +	    if (!cache) +		continue; +	    if (cache->pid) { +		kill(cache->pid, SIGKILL);  #ifdef HAVE_WAITPID -	    waitpid(image_pid, &wait_st, 0); +		waitpid(cache->pid, &wait_st, 0);  #else -	    wait(&wait_st); +		wait(&wait_st);  #endif -	    image_pid = 0; +		cache->pid = 0; +	    } +	    unlink(cache->touch); +	    image_cache[i] = NULL;  	} -	image_cache = NULL;  	image_list = NULL;  	image_file = NULL; +	if (image_lock) +	    unlink(image_lock);  	need_load_image = FALSE;  	return;      } -    if (flag == IMG_FLAG_NEXT && need_load_image) { -	struct stat st; -	if (image_pid) { +    if (need_load_image) { +	int draw = FALSE; +	for (i = 0; i < max_load_image; i++) { +	    cache = image_cache[i]; +	    if (!cache) +		continue; +#ifdef HAVE_READLINK +	    if (lstat(cache->touch, &st)) +#else +	    if (stat(cache->touch, &st)) +#endif +		continue; +	    if (cache->pid) { +		kill(cache->pid, SIGKILL);  #ifdef HAVE_WAITPID -	    waitpid(image_pid, &wait_st, 0); +		waitpid(cache->pid, &wait_st, 0);  #else -	    wait(&wait_st); +		wait(&wait_st);  #endif -	    image_pid = 0; -	} -	if (!stat(image_cache->file, &st)) { -	    image_cache->loaded = IMG_FLAG_LOADED; -	    if (getImageSize(image_cache)) { -		if (Currentbuf) -		    Currentbuf->need_reshape = TRUE; +		cache->pid = 0;  	    } +	    if (!stat(cache->file, &st)) { +		cache->loaded = IMG_FLAG_LOADED; +		if (getImageSize(cache)) { +		    if (flag == IMG_FLAG_NEXT && Currentbuf) +			Currentbuf->need_reshape = TRUE; +		} +		draw = TRUE; +	    } +	    else +		cache->loaded = IMG_FLAG_ERROR; +	    unlink(cache->touch); +	    image_cache[i] = NULL;  	} -	else { -	    image_cache->loaded = IMG_FLAG_ERROR; -	} -	image_cache = NULL; -	drawImage(); +	if (flag == IMG_FLAG_NEXT && draw) +	    drawImage();      } +    if (image_lock) +	unlink(image_lock);      need_load_image = FALSE; -    if (flag == IMG_FLAG_START) -	signal(SIGUSR1, load_image_handler); -    else -	signal(SIGUSR1, load_image_next); +    signal(SIGUSR1, load_image_handler); -    if (image_cache) -	return; - -    image_pid = 0;      if (!image_list)  	return; -    while (1) { -	image_cache = (ImageCache *) popValue(image_list); -	if (!image_cache) { -	    if (Currentbuf && Currentbuf->need_reshape) -		displayBuffer(Currentbuf, B_NORMAL); -	    return; +    for (i = 0; i < max_load_image; i++) { +	if (image_cache[i]) +	    continue; +	while (1) { +	    cache = (ImageCache *) popValue(image_list); +	    if (!cache) { +		for (i = 0; i < max_load_image; i++) { +		    if (image_cache[i]) +			goto load_image_end; +		} +		image_list = NULL; +		image_file = NULL; +		if (Currentbuf && Currentbuf->need_reshape) +		    displayBuffer(Currentbuf, B_NORMAL); +		return; +	    } +	    if (cache->loaded == IMG_FLAG_UNLOADED) +		break;  	} -	if (image_cache->loaded == IMG_FLAG_UNLOADED) -	    break; -    } +	image_cache[i] = cache; -    flush_tty(); -    if ((image_pid = fork()) == 0) { -	Buffer *b; +	if (!image_lock) { +	    image_lock = tmpfname(TMPF_DFL, ".lock")->ptr; +	    pushText(fileToDelete, image_lock); +	} -	reset_signals(); -	signal(SIGINT, SIG_IGN); -	close_tty(); -	QuietMessage = TRUE; -	fmInitialized = FALSE; -	image_source = image_cache->file; -	b = loadGeneralFile(image_cache->url, image_cache->current, NULL, 0, -			    NULL); -	if (!b || !b->real_type || strncasecmp(b->real_type, "image/", 6)) -	    unlink(image_cache->file); -	kill(getppid(), SIGUSR1); -	exit(0); +	flush_tty(); +	if ((cache->pid = fork()) == 0) { +	    Buffer *b; +#ifndef HAVE_READLINK +	    FILE *f; +#endif +	    reset_signals(); +	    signal(SIGINT, SIG_IGN); +	    close_tty(); +	    QuietMessage = TRUE; +	    fmInitialized = FALSE; +	    image_source = cache->file; +	    b = loadGeneralFile(cache->url, cache->current, NULL, 0, NULL); +	    if (!b || !b->real_type || strncasecmp(b->real_type, "image/", 6)) +		unlink(cache->file); +#ifdef HAVE_READLINK +	    symlink(cache->file, cache->touch); +	    if (lstat(image_lock, &st)) { +		symlink(cache->file, image_lock); +#else +	    f = fopen(cache->touch, "w"); +	    if (f) +		fclose(f); +	    if (stat(image_lock, &st)) { +		f = fopen(image_lock, "w"); +		if (f) +		    fclose(f); +#endif +		kill(getppid(), SIGUSR1); +	    } +	    exit(0); +	} +	else if (cache->pid < 0) { +	    cache->pid = 0; +	    return; +	}      } +  load_image_end: +    if (flag == IMG_FLAG_NEXT) +	signal(SIGUSR1, load_image_next);  }  ImageCache * @@ -451,12 +512,15 @@ getImage(Image * image, ParsedURL *current, int flag)  	cache->url = image->url;  	cache->current = current;  	cache->file = tmpfname(TMPF_DFL, image->ext)->ptr; +	cache->touch = tmpfname(TMPF_DFL, NULL)->ptr; +	cache->pid = 0;  	cache->index = 0;  	cache->loaded = IMG_FLAG_UNLOADED;  	cache->width = image->width;  	cache->height = image->height;  	putHash_sv(image_hash, key->ptr, (void *)cache);  	pushText(fileToDelete, cache->file); +	pushText(fileToDelete, cache->touch);      }      if (flag != IMG_FLAG_SKIP) {  	if (cache->loaded == IMG_FLAG_UNLOADED) { @@ -485,10 +549,10 @@ getImageSize(ImageCache * cache)      int w = 0, h = 0;      if (!activeImage) -	return 0; +	return FALSE;      if (!cache || cache->loaded != IMG_FLAG_LOADED ||  	(cache->width > 0 && cache->height > 0)) -	return 0; +	return FALSE;      tmp = Strnew();      if (!strchr(Imgsize, '/'))  	Strcat_m_charp(tmp, LIB_DIR, "/", NULL); @@ -496,12 +560,15 @@ getImageSize(ImageCache * cache)  		   " 2> /dev/null", NULL);      f = popen(tmp->ptr, "r");      if (!f) -	return 0; -    fscanf(f, "%d %d", &w, &h); +	return FALSE; +    while (fscanf(f, "%d %d", &w, &h) < 0) { +	if (feof(f)) +	    break; +    }      pclose(f);      if (!(w > 0 && h > 0)) -	return 0; +	return FALSE;      w = (int)(w * image_scale / 100 + 0.5);      if (w == 0)  	w = 1; @@ -524,6 +591,6 @@ getImageSize(ImageCache * cache)  	cache->height = 1;      tmp = Sprintf("%d;%d;%s", cache->width, cache->height, cache->url);      putHash_sv(image_hash, tmp->ptr, (void *)cache); -    return 1; +    return TRUE;  }  #endif | 
