~ft/zuke

6d6c45d94e4a4a3eebf344f646027a6e939b45d2 — Sigrid Haflínudóttir 7 months ago 4af9aa8
fix crash reported by qwx; harden player logic, print more useful info when something goes wrong
1 files changed, 39 insertions(+), 37 deletions(-)

M zuke.c
M zuke.c => zuke.c +39 -37
@@ 404,7 404,7 @@ newplayer(int pcur, int loadnext)
	player->ev = chancreate(sizeof(ulong), 0);
	player->pcur = pcur;

	threadcreate(playerthread, player, mainstacksize);
	threadcreate(playerthread, player, 4096);
	if(playerret(player) < 0)
		return nil;



@@ 431,7 431,8 @@ playerthread(void *player_)
	Ioproc *io;
	Image *thiscover;
	ulong c;
	int p[2], fd, pid, n, noinit, trycoverload;
	int p[2], fd, pid, noinit, trycoverload;
	long n, r;
	u64int bytesfrom, bf;
	Meta *cur;



@@ 481,10 482,11 @@ restart:
	if(!noinit){
		sendul(player->ev, Evready);
		buf = malloc(Relbufsz);
		io = ioproc();
		n = ioreadn(io, p[1], buf, Relbufsz);
		c = recvul(player->ctl);
		if(c != Cstart)
		if((io = ioproc()) == nil)
			sysfatal("player: %r");
		if((n = ioreadn(io, p[1], buf, Relbufsz)) < 0)
			fprint(2, "player: %r\n");
		if(n < 1 || recv(player->ctl, &c) < 0 || c != Cstart)
			goto freeplayer;
		byteswritten = iowrite(io, audio, buf, n);
		bytesfrom = 0;


@@ 501,7 503,7 @@ restart:
		if(bytesfrom > byteswritten && n > bytesfrom-byteswritten)
			n = bytesfrom-byteswritten;
		n = ioreadn(io, p[1], buf, n);
		if(n < 0)
		if(n <= 0)
			break;

		thiscover = nil;


@@ 511,36 513,36 @@ restart:
			redraw(1);
			player->img = nil;
		}
		c = nbrecvul(player->ctl);
		bf = bytesfrom != 0 ? bytesfrom : byteswritten;
		if(c == Cstop || c == -1)
		r = nbrecv(player->ctl, &c);
		if(r < 0){
			goto stop;
		if(c == Ctoggle){
			c = recvul(player->ctl);
			if(c == Cstop)
		}else if(r != 0){
			if(c == Ctoggle){
				if(recv(player->ctl, &c) < 0 || c == Cstop)
					goto stop;
			}else if(c == Cforward){
				bytesfrom = bf + Seekbytes;
			}else if(c == Cforwardfast){
				bytesfrom = bf + Seekbytesfast;
			}else if(c == Cbackward){ /* to seek backwards we need to restart playback */
				bytesfrom = bf >= Seekbytes ? bf - Seekbytes : 0;
				n = 0; /* not an error */
				break;
			}else if(c == Cbackwardfast){
				bytesfrom = bf >= Seekbytesfast ? bf - Seekbytesfast : 0;
				n = 0; /* not an error */
				break;
			}else{ /* Cstop */
				goto stop;
		}else if(c == Cforward){
			bytesfrom = bf + Seekbytes;
		}else if(c == Cforwardfast){
			bytesfrom = bf + Seekbytesfast;
		}else if(c == Cbackward){ /* to seek backwards we need to restart playback */
			bytesfrom = bf >= Seekbytes ? bf - Seekbytes : 0;
			n = 0; /* not an error */
			break;
		}else if(c == Cbackwardfast){
			bytesfrom = bf >= Seekbytesfast ? bf - Seekbytesfast : 0;
			n = 0; /* not an error */
			break;
			}
		}

		c = 0;
		if(bytesfrom <= byteswritten){
			if(bytesfrom == byteswritten)
				bytesfrom = 0;
			if(iowrite(io, audio, buf, n) != n){
				fprint(2, "failed to write %d bytes: %r\n", n);
				break;
			}
			if(iowrite(io, audio, buf, n) != n)
				fprint(2, "player: %r\n");
			if(trycoverload && byteswritten >= Bps){
				player->img = chancreate(sizeof(Image*), 0);
				proccreate(coverload, player, 4096);


@@ 554,6 556,7 @@ restart:

	if(n < 1){ /* seeking backwards or end of the song */
		close(p[1]);
		p[1] = -1;
		if(c != Cbackward && c != Cbackwardfast){
			playercurr = nil;
			playercurr = newplayer((player->pcur+1) % plnum, 1);


@@ 567,20 570,19 @@ stop:
	if(player->img != nil)
		freeimage(recvp(player->img));
freeplayer:
	chanfree(player->ctl);
	chanfree(player->ev);
	if(pid >= 0)
		postnote(PNGROUP, pid, "interrupt");
	closeioproc(io);
	if(p[1] >= 0)
		close(p[1]);
	if(player == playercurr)
		playercurr = nil;
	if(player == playernext)
		playernext = nil;
	chanclose(player->ctl);
	chanclose(player->ev);
	chanfree(player->ctl);
	chanfree(player->ev);
	close(p[1]);
	closeioproc(io);
	free(buf);
	free(player);
	if(pid >= 0)
		postnote(PNGROUP, pid, "interrupt");
	threadexits(nil);
}