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);
}
/*
--
⑨