]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/port/chan.c
kernel: fix fairshare formula in comment (thanks erik)
[plan9front.git] / sys / src / 9 / port / chan.c
index ff3b8e5f351e2dee66117754d1cec8ff6b9ae7b7..c74fb5d51d485e760f60b2d394e100ede48dfb00 100644 (file)
@@ -114,7 +114,6 @@ decref(Ref *r)
        unlock(r);
        if(x < 0)
                panic("decref pc=%#p", getcallerpc(&r));
-
        return x;
 }
 
@@ -130,20 +129,19 @@ kstrcpy(char *s, char *t, int ns)
        int nt;
 
        nt = strlen(t);
-       if(nt+1 <= ns){
-               memmove(s, t, nt+1);
-               return;
-       }
-       /* too long */
-       if(ns < 4){
-               /* but very short! */
-               strncpy(s, t, ns);
+       if(nt < ns){
+               memmove(s, t, nt);
+               s[nt] = '\0';
                return;
        }
-       /* truncate with ... at character boundary (very rare case) */
-       memmove(s, t, ns-4);
+       /* too long, truncate */
+       nt = ns-1;
+       memmove(s, t, nt);
+       s[nt] = '\0';
+       /* append ... if there is space */
        ns -= 4;
-       s[ns] = '\0';
+       if(ns < 0)
+               return;
        /* look for first byte of UTF-8 sequence by skipping continuation bytes */
        while(ns>0 && (s[--ns]&0xC0)==0x80)
                ;
@@ -169,17 +167,18 @@ kstrdup(char **p, char *s)
        int n;
        char *t, *prev;
 
-       n = strlen(s)+1;
+       n = strlen(s);
        /* if it's a user, we can wait for memory; if not, something's very wrong */
-       if(up){
-               t = smalloc(n);
-               setmalloctag(t, getcallerpc(&p));
-       }else{
-               t = malloc(n);
+       if(up != nil)
+               t = smalloc(n+1);
+       else{
+               t = malloc(n+1);
                if(t == nil)
                        panic("kstrdup: no memory");
        }
+       setmalloctag(t, getcallerpc(&p));
        memmove(t, s, n);
+       t[n] = '\0';
        prev = *p;
        *p = t;
        free(prev);
@@ -195,6 +194,8 @@ chandevreset(void)
                devtab[i]->reset();
 }
 
+static void closeproc(void*);
+
 void
 chandevinit(void)
 {
@@ -202,6 +203,7 @@ chandevinit(void)
 
        for(i=0; devtab[i] != nil; i++)
                devtab[i]->init();
+       kproc("closeproc", closeproc, nil);
 }
 
 void
@@ -477,8 +479,8 @@ chanfree(Chan *c)
 struct {
        Chan *head;
        Chan *tail;
-       int nqueued;
-       int nclosed;
+       ulong nqueued;
+       ulong nclosed;  
        Lock l;
        QLock q;
        Rendez r;
@@ -491,58 +493,73 @@ clunkwork(void*)
 }
 
 static void
-closeproc(void*)
+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);
+       wakeup(&clunkq.r);
+}
+
+static Chan*
+closechandeq(void)
+{
+       Chan *c;
+
+       lock(&clunkq.l);
+       c = clunkq.head;
+       if(c != nil) {
+               clunkq.head = c->next;
+               clunkq.nclosed++;
+       }
+       unlock(&clunkq.l);
+       return c;
+}
+
+static void
+closeproc(void *)
 {
        Chan *c;
 
        for(;;){
-               if(clunkq.head == nil){
-                       if(!waserror()){
-                               tsleep(&clunkq.r, clunkwork, nil, 5000);
+               c = closechandeq();
+               if(c == nil) {
+                       qlock(&clunkq.q);
+                       if(!waserror()) {
+                               tsleep(&clunkq.r, clunkwork, nil, 500);
                                poperror();
                        }
+                       c = closechandeq();
+                       if(c == nil) {
+                               if(clunkq.q.head != nil) {
+                                       qunlock(&clunkq.q);
+                                       pexit("no work", 1);
+                               }
+                               qunlock(&clunkq.q);
+                               continue;
+                       }
+                       if(clunkq.q.head == nil) {
+                               if(!waserror()) {
+                                       kproc("closeproc", closeproc, nil);
+                                       poperror();
+                               }
+                       }
+                       qunlock(&clunkq.q);
                }
-               qunlock(&clunkq.q);
-               lock(&clunkq.l);
-               c = clunkq.head;
-               if(c == nil){
-                       unlock(&clunkq.l);
-                       pexit("no work", 1);
-               }
-               clunkq.head = c->next;
-               clunkq.nclosed++;
-               unlock(&clunkq.l);
                if(!waserror()){
                        devtab[c->type]->close(c);
                        poperror();
                }
                chanfree(c);
-               qlock(&clunkq.q);
        }
 }
 
-static void
-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(up != 0 && palloc.Lock.p != up && canqlock(&clunkq.q)){
-               c = up->dot;
-               up->dot = nil;
-               kproc("closeproc", closeproc, nil);
-               up->dot = c;
-       }else
-               wakeup(&clunkq.r);
-}
-
 void
 cclose(Chan *c)
 {
@@ -556,7 +573,8 @@ cclose(Chan *c)
 
        if(devtab[c->type]->dc == L'M')
        if((c->flag&(CRCLOSE|CCACHE)) == CCACHE)
-       if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0){
+       if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0)
+       if((clunkq.nqueued - clunkq.nclosed) < 64){
                closechanq(c);
                return;
        }
@@ -1002,7 +1020,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
                                *nerror = nhave;
                        pathclose(path);
                        cclose(c);
-                       strcpy(up->errstr, Enotdir);
+                       kstrcpy(up->errstr, Enotdir, ERRMAX);
                        if(mh != nil)
                                putmhead(mh);
                        return -1;
@@ -1083,11 +1101,11 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
                                        if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
                                                if(nerror)
                                                        *nerror = nhave+wq->nqid+1;
-                                               strcpy(up->errstr, Edoesnotexist);
+                                               kstrcpy(up->errstr, Edoesnotexist, ERRMAX);
                                        }else{
                                                if(nerror)
                                                        *nerror = nhave+wq->nqid;
-                                               strcpy(up->errstr, Enotdir);
+                                               kstrcpy(up->errstr, Enotdir, ERRMAX);
                                        }
                                        free(wq);
                                        if(mh != nil)
@@ -1153,7 +1171,7 @@ createdir(Chan *c, Mhead *m)
                nexterror();
        }
        for(f = m->mount; f; f = f->next){
-               if(f->mflag&MCREATE){
+               if(f->to != nil && (f->mflag&MCREATE) != 0){
                        nc = cclone(f->to);
                        runlock(&m->lock);
                        poperror();
@@ -1472,6 +1490,10 @@ namec(char *aname, int amode, int omode, ulong perm)
                /* save&update the name; domount might change c */
                path = c->path;
                incref(path);
+               if(waserror()){
+                       pathclose(path);
+                       nexterror();
+               }
                m = nil;
                if(!nomount)
                        domount(&c, &m, &path);
@@ -1482,6 +1504,7 @@ namec(char *aname, int amode, int omode, ulong perm)
                /* now it's our copy anyway, we can put the name back */
                pathclose(c->path);
                c->path = path;
+               poperror();
 
                /* record whether c is on a mount point */
                c->ismtpt = m!=nil;