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));