diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2024-02-11 15:18:27 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2024-02-11 15:18:27 +0000 |
commit | 7aeae86d36a1a04e93bb4be2216cb735acfab714 (patch) | |
tree | 88d113a905ea73fb2f32cc43283bed3decae3e76 /main.c | |
parent | 7c6a945996a1d5510ff1412320ac7d07a0f82851 (diff) |
More work
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 124 |
1 files changed, 79 insertions, 45 deletions
@@ -13,6 +13,8 @@ #define Eoffset "can't write to this file at non-zero offset" #define Ebadctl "bad ctl message" +QLock guilock = 0; + char *username; enum { @@ -88,19 +90,35 @@ mkpropqid(int proptag) void settype(GuiElement *g, int type) { + GuiSpec spec = guispecs[type]; - free(g->props); - g->type = type; - - g->nprops = spec.nprops; - g->props = emalloc(sizeof(Prop) * spec.nprops); + int nprops = spec.nprops + nbaseprops; + /* Allocate the props before locking the gui element, as some of the + * allocations might cause this thread to block + */ + + Prop *props = emalloc(sizeof(Prop) * nprops); + for(int i = 0; i < nbaseprops; i++){ + int tag = baseprops[i]; + props[i].tag = tag; + props[i].val = propspecs[tag].def(); + props[i].qid = mkpropqid(tag); + } for(int i = 0; i < spec.nprops; i++){ int tag = spec.proptags[i]; - g->props[i].tag = tag; - g->props[i].val = propspecs[tag].def(); - g->props[i].qid = mkpropqid(tag); + props[i+nbaseprops].tag = tag; + props[i+nbaseprops].val = propspecs[tag].def(); + props[i+nbaseprops].qid = mkpropqid(tag); } + wlock(&g->lock); + /* TODO: free old propvals */ + free(g->props); + g->type = type; + g->nprops = nprops; + g->props = props; + wunlock(&g->lock); + updategui(0); /* redraw everything */ } @@ -108,7 +126,6 @@ GuiElement * newgui(GuiElement *parent) { GuiElement *g = emalloc(sizeof(GuiElement)); - memset(g, 0, sizeof(GuiElement)); g->parent = parent; g->qid = mkqid(Qdir); g->qclone = mkqid(Qclone); @@ -118,9 +135,11 @@ newgui(GuiElement *parent) if(parent){ g->id = parent->nchildren; + wlock(&parent->lock); parent->nchildren++; parent->children = erealloc(parent->children, parent->nchildren * sizeof(GuiElement *)); parent->children[g->id] = g; + wunlock(&parent->lock); } settype(g, Gcontainer); @@ -137,10 +156,11 @@ findchild(GuiElement *g, char *name) return nil; } - if(id < g->nchildren) - return g->children[id]; + rlock(&g->lock); + GuiElement *child = (id < g->nchildren) ? g->children[id] : nil; + runlock(&g->lock); - return nil; + return child; } void @@ -164,6 +184,7 @@ fswalk1(Fid *fid, char *name, Qid *qid) { GuiElement *g = fid->aux; GuiElement *child; + char *err = nil; switch(QID_TYPE(fid->qid)){ case Qdir: @@ -174,41 +195,43 @@ fswalk1(Fid *fid, char *name, Qid *qid) fid->aux = g->parent; *qid = g->parent->qid; } - return nil; - }else if(strcmp(name, "clone") == 0){ + }else if(strcmp(name, "clone") == 0) *qid = g->qclone; - return nil; - }else if(strcmp(name, "event") == 0){ + else if(strcmp(name, "event") == 0) *qid = g->qevent; - return nil; - }else if(strcmp(name, "type") == 0){ + else if(strcmp(name, "type") == 0) *qid = g->qtype; - return nil; - }else if(strcmp(name, "props") == 0){ + else if(strcmp(name, "props") == 0) *qid = g->qprops; - return nil; - }else if(child = findchild(g, name)){ + else if(child = findchild(g, name)){ fid->aux = child; *qid = child->qid; - return nil; - } - return Eexist; + }else + err = Eexist; + break; case Qprops: - if(strcmp(name, "..") == 0){ + if(strcmp(name, "..") == 0) *qid = g->qid; - return nil; - } - for(int i = 0; i < g->nprops; i++){ - PropSpec spec = propspecs[g->props[i].tag]; - if(strcmp(name, spec.name) == 0){ - *qid = g->props[i].qid; - return nil; + else{ + rlock(&g->lock); + int ok = 0; + for(int i = 0; i < g->nprops && ok == 0; i++){ + PropSpec spec = propspecs[g->props[i].tag]; + if(strcmp(name, spec.name) == 0){ + *qid = g->props[i].qid; + ok = 1; + } } + runlock(&g->lock); + if(!ok) + err = Eexist; } - return Eexist; + break; default: - return Enodir; + err = Enodir; + break; } + return err; } char * @@ -310,7 +333,10 @@ dirtreegen(int n, Dir *d, void *aux) }else n -= Fmax; - if(g && n < g->nchildren){ + rlock(&g->lock); + int done = n >= g->nchildren; + + if(!done){ GuiElement *child = g->children[n]; d->mode = DMDIR|0555; @@ -319,10 +345,10 @@ dirtreegen(int n, Dir *d, void *aux) char buf[64]; snprint(buf, sizeof(buf), "%d", child->id); d->name = estrdup9p(buf); - return 0; } + runlock(&g->lock); - return -1; + return done ? -1 : 0; } int @@ -334,14 +360,20 @@ proptreegen(int n, Dir *d, void *aux) d->gid = estrdup9p(username); d->muid = estrdup9p(username); - if(n >= g->nprops) - return -1; + int done; + + rlock(&g->lock); + done = n >= g->nprops; + + if(!done){ + PropSpec spec = propspecs[g->props[n].tag]; + d->mode = 0666; + d->name = estrdup9p(spec.name); + d->qid = g->props[n].qid; + } + runlock(&g->lock); - PropSpec spec = propspecs[g->props[n].tag]; - d->mode = 0666; - d->name = estrdup9p(spec.name); - d->qid = g->props[n].qid; - return 0; + return done ? -1 : 0; } void @@ -365,7 +397,9 @@ fsread(Req *r) readstr(r, "eveeent\n"); break; case Qtype: + rlock(&g->lock); snprint(buf, sizeof(buf), "%s\n", guispecs[g->type].name); + runlock(&g->lock); readstr(r, buf); break; case Qprops: |