git: 9front

Download patch

ref: 96a3ed60069c4270a9bfd4c37416fac69740c469
parent: f43c26ec78a864ff4063221526f7c6c9d7c633c6
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Apr 28 05:12:04 EDT 2012

avoid leaking up->dot into the closeproc

--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -520,54 +520,64 @@
 }
 
 static void
-closechan(Chan *c, int sync)
+closechanq(Chan *c)
 {
+	lock(&clunkq.l);
+	clunkq.nqueued++;
+	c->next = nil;
+	if(clunkq.head)
+		clunkq.tail->next = c;
+	else
+		clunkq.head = c;
+	clunkq.tail = c;
+	unlock(&clunkq.l);
+
+	if(canqlock(&clunkq.q)){
+		c = up->dot;
+		up->dot = nil;
+		kproc("closeproc", closeproc, nil);
+		up->dot = c;
+	}else
+		wakeup(&clunkq.r);
+}
+
+void
+cclose(Chan *c)
+{
 	if(c == nil || c->ref < 1 || c->flag&CFREE)
-		panic("closechan %#p", getcallerpc(&c));
+		panic("cclose %#p", getcallerpc(&c));
 
-	DBG("closechan %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
+	DBG("cclose %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
 
 	if(decref(c))
 		return;
 
+	if(devtab[c->type]->dc == L'M')
 	if((c->flag&(CRCLOSE|CCACHE)) == CCACHE)
-	if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0)
-		sync = 0;
+	if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0){
+		closechanq(c);
+		return;
+	}
 
-	if(sync){
-		if(!waserror()){
-			devtab[c->type]->close(c);
-			poperror();
-		}
-		chanfree(c);
-	} else {
-		lock(&clunkq.l);
-		clunkq.nqueued++;
-		c->next = nil;
-		if(clunkq.head)
-			clunkq.tail->next = c;
-		else
-			clunkq.head = c;
-		clunkq.tail = c;
-		unlock(&clunkq.l);
-
-		if(canqlock(&clunkq.q))
-			kproc("closeproc", closeproc, nil);
-		else
-			wakeup(&clunkq.r);
+	if(!waserror()){
+		devtab[c->type]->close(c);
+		poperror();
 	}
+	chanfree(c);
 }
 
 void
-cclose(Chan *c)
-{
-	closechan(c, 1);
-}
-
-void
 ccloseq(Chan *c)
 {
-	closechan(c, 0);
+	if(c == nil || c->ref < 1 || c->flag&CFREE)
+		panic("ccloseq %#p", getcallerpc(&c));
+
+	DBG("ccloseq %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
+
+	if(decref(c))
+		return;
+
+	closechanq(c);
 }
 
 /*
--