shithub: patch

Download patch

ref: 7caa9585434c771bea1aaf6d3317b969df5afa9d
parent: 3362539850d86c68b403202d113c67f2cd858fca
author: qwx <qwx@sciops.net>
date: Fri Dec 31 14:25:16 EST 2021

page-del: fix locking, list popping, add separate pop command

--- a/page-del
+++ b/page-del
@@ -1,23 +1,29 @@
 diff 855cf4326f5a07d7142c2d8918f5fa856d912b85 uncommitted
---- a//sys/src/cmd/page.c
-+++ b//sys/src/cmd/page.c
-@@ -74,6 +74,7 @@
+--- a/sys/src/cmd/page.c
++++ b/sys/src/cmd/page.c
+@@ -74,7 +74,10 @@
  	Czerox,
  	Cwrite,
  	Cext,
-+	Cdel,
++	Cpop,
  	Cdummy2,
++	Cdelete,
++	Cdummy3,
  	Cquit,
  };
-@@ -98,6 +99,7 @@
+ 
+@@ -98,7 +101,10 @@
  	[Czerox]	"zerox",	'z', 0, 0,
  	[Cwrite]	"write",	'w', 0, 0,
  	[Cext]		"ext",		'x', 0, 0,
-+	[Cdel]		"del",		'd', 0, 0,
++	[Cpop]		"pop",		'p', 0, 0,
  	[Cdummy2]	"",		0, 0, 0,
++	[Cdelete]	"delete",	'D', 0, 0,
++	[Cdummy3]	"",		0, 0, 0,
  	[Cquit]		"quit",		'q', Kdel, Keof,
  };
-@@ -134,6 +136,7 @@
+ 
+@@ -134,6 +140,7 @@
  void showpage(Page *);
  void drawpage(Page *);
  Point pagesize(Page *);
@@ -25,7 +31,7 @@
  
  Page*
  addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd)
-@@ -986,6 +989,54 @@
+@@ -986,6 +993,71 @@
  	}
  }
  
@@ -32,23 +38,14 @@
 +/* page entries are never freed, there's no point
 + * and would break everything */
 +Page*
-+delpage(Page *p)
++poppage(Page *p)
 +{
 +	Page *t, *q;
 +
 +	if(p == nil)
 +		return nil;
-+	/* to remove(2) subpages in documents makes no sense, and just
-+	 * removing a subentry doesn't seem like a feature worth the bother */
 +	if(p->up != root)
 +		return p;
-+	if(p->fd >= 0)
-+		close(p->fd);
-+	p->fd = -1;
-+	if(remove(p->name) < 0){
-+		fprint(2, "remove %s: %r", p->name);
-+		return p;
-+	}
 +	qlock(&pagelock);
 +	for(t = p->down; t != nil && t->up != root; t = q){
 +		qlock(t);
@@ -67,20 +64,46 @@
 +	free(p->name);
 +	free(p->data);
 +	p->name = p->data = nil;
-+	if(root->down != p){
-+		t = prevpage(p);
-+		t->next = p->next;
-+	}else
++	t = prevpage(p);
++	if(root->tail == p)
++		root->tail = t;
++	if(root->down == p || t == nil)
 +		root->down = p->next;
++	else
++		t->next = p->next;
 +	qunlock(&pagelock);
 +	qunlock(p);
-+	return p->next != nil ? p->next : t;
++	if(p->next != nil){
++		forward = 1;
++		return p->next;
++	}
++	forward = -1;
++	return t;
 +}
 +
++Page*
++delpage(Page *p)
++{
++	if(p == nil)
++		return nil;
++	/* to remove(2) subpages in documents makes no sense, and just
++	 * removing a subentry doesn't seem like a feature worth the bother */
++	if(p->up != root)
++		return p;
++	if(p->fd >= 0)
++		close(p->fd);
++	p->fd = -1;
++	if(remove(p->name) < 0){
++		fprint(2, "remove %s: %r", p->name);
++		return p;
++	}
++	return poppage(p);
++}
++
  /*
   * A draw operation that touches only the area contained in bot but not in top.
   * mp and sp get aligned with bot.min.
-@@ -1461,6 +1512,7 @@
+@@ -1461,6 +1533,7 @@
  	char buf[NPATH], *s;
  	Point o;
  	int fd;
@@ -88,21 +111,32 @@
  
  	switch(i){
  	case Corigsize:
-@@ -1545,6 +1597,17 @@
- 		break;
+@@ -1546,6 +1619,28 @@
  	case Csnarf:
  		writeaddr(current, "/dev/snarf");
-+		break;
-+	case Cdel:
+ 		break;
++	case Cpop:
 +		if(current == nil || !canqlock(current))
 +			break;
-+		if((p = delpage(current)) == current)
++		if((p = poppage(current)) == current)
 +			break;
++	Reset:
 +		current = p;
-+		if(current == nil)
++		if(current == nil){
++			drawlock(0);
++			draw(screen, screen->r, paper, nil, ZP);
++			drawframe(screen->r);
++			drawlock(1);
 +			break;
-+		forward = 1;
++		}
 +		showpage(current);
- 		break;
++		break;
++	case Cdelete:
++		if(current == nil || !canqlock(current))
++			break;
++		if((p = delpage(current)) == current)
++			break;
++		goto Reset;
  	case Cnext:
  		forward = 1;
+ 		showpage(nextpage(current));