void convhangup(Conv *c) { c->hangup = 1; c->rpc.op = 0; (*c->kickreply)(c); nbsendp(c->rpcwait, 0); }
static void etherreadproc(void *a) { int i, n, nwants; Buf *bp, *dbp; Ether *e = a; threadsetname("etherread"); while(e->exiting == 0){ bp = nbrecvp(e->rc); if(bp == nil){ bp = allocbuf(e); /* leak() may think we leak */ if(e->bread(e, bp) < 0){ freebuf(e, bp); break; } if(bp->ndata == 0){ /* may be a short packet; continue */ if(0)dprint(2, "%s: read: short\n", argv0); freebuf(e, bp); continue; }else setbuftype(bp); } e->nin++; nwants = 0; for(i = 0; i < e->nconns; i++) nwants += cwantsbp(e->conns[i], bp); for(i = 0; nwants > 0 && i < e->nconns; i++) if(cwantsbp(e->conns[i], bp)){ n = bp->ndata; if(e->conns[i]->type == -2 && n > 64) n = 64; if(nwants-- == 1){ bp->ndata = n; dbp = bp; bp = nil; }else{ dbp = allocbuf(e); memmove(dbp->rp, bp->rp, n); dbp->ndata = n; dbp->type = bp->type; } if(nbsendp(e->conns[i]->rc, dbp) == 0){ deprint(2, "%s: (in) packet lost\n", argv0); e->nierrs++; freebuf(e, dbp); } } freebuf(e, bp); } deprint(2, "%s: writeproc exiting\n", argv0); etherexiting(e); closedev(e->dev); usbfsdel(&e->fs); }
static int32_t fswrite(Usbfs *fs, Fid *fid, void *data, int32_t count, int64_t) { int cn, qt; char buf[128]; Buf *bp; Conn *c; Ether *e; Qid q; q = fid->qid; q.path &= ~fs->qid; e = fs->aux; qt = qtype(q.path); cn = qnum(q.path); switch(qt){ case Qndata: c = getconn(e, cn, 0); if(c == nil){ werrstr(Eio); return -1; } bp = allocbuf(e); if(count > sizeof(bp->data)-Hdrsize) count = sizeof(bp->data)-Hdrsize; memmove(bp->rp, data, count); bp->ndata = count; if(etherdebug > 1) dumpframe("etherout", bp->rp, bp->ndata); if(e->nblock == 0) sendp(e->wc, bp); else if(nbsendp(e->wc, bp) == 0){ deprint(2, "%s: (out) packet lost\n", argv0); e->noerrs++; freebuf(e, bp); } break; case Qnctl: c = getconn(e, cn, 0); if(c == nil){ werrstr(Eio); return -1; } if(count > sizeof(buf) - 1) count = sizeof(buf) - 1; memmove(buf, data, count); buf[count] = 0; if(etherctl(e, c, buf) < 0) return -1; break; default: sysfatal("usb: ether: fsread bug"); } return count; }
void convreset(Conv *c) { if(c->ref != 1){ c->hangup = 1; nbsendp(c->rpcwait, 0); while(c->ref > 1) yield(); c->hangup = 0; } c->state = "nascent"; c->err[0] = '\0'; freeattr(c->attr); c->attr = nil; c->proto = nil; c->rpc.op = 0; c->active = 0; c->done = 0; c->hangup = 0; }
static void addwarningtext(Mntdir *md, Rune *r, int nr) { Warning *warn; for(warn = warnings; warn; warn=warn->next){ if(warn->md == md){ bufinsert(&warn->buf, warn->buf.nc, r, nr); return; } } warn = emalloc(sizeof(Warning)); warn->next = warnings; warn->md = md; if(md) fsysincid(md); warnings = warn; bufinsert(&warn->buf, 0, r, nr); nbsendp(cwarn, 0); }
void addrefresh(Page *p, char *fmt, ...) { Refresh *r; Rune *s; va_list arg; if(p->aborting) return; va_start(arg, fmt); s = runevsmprint(fmt, arg); va_end(arg); if(s == nil) error("runevsmprint failed"); qlock(&refreshlock); if(p->status) { free(p->status); p->status = nil; } p->status = s; for(r=refreshs; r!=nil; r=r->next) if(r->p == p) goto Return; incref(p->w); /* flushrefresh will decref */ r = emalloc(sizeof(Refresh)); r->p = p; r->next = refreshs; refreshs = r; Return: nbsendp(crefresh, nil); qunlock(&refreshlock); }
static void kickwriter(Client *c) { nbsendp(c->writerkick, nil); }
void connoutthread(void *arg) { int err; Conn *c; Msg *m, *om; Ioproc *io; c = arg; io = ioproc(); threadsetname("connout %s", c->dir); while((m = recvq(c->outq)) != nil){ err = m->tx.type+1 != m->rx.type; if(!err && m->isopenfd) if(xopenfd(m) < 0) continue; switch(m->tx.type){ case Tflush: om = m->oldm; if(om) if(delhash(om->c->tag, om->ctag, om) == 0) msgput(om); break; case Tclunk: case Tremove: if(m->fid) if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) fidput(m->fid); break; case Tauth: if(err && m->afid){ if(verbose) fprint(2, "%T auth error\n"); if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0) fidput(m->afid); } break; case Tattach: if(err && m->fid) if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) fidput(m->fid); break; case Twalk: if(err || m->rx.nwqid < m->tx.nwname) if(m->tx.fid != m->tx.newfid && m->newfid) if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0) fidput(m->newfid); break; case Tread: break; case Tstat: break; case Topen: case Tcreate: m->fid->isdir = (m->rx.qid.type & QTDIR); break; } if(delhash(m->c->tag, m->ctag, m) == 0) msgput(m); if(verbose > 1) fprint(2, "%T fd#%d <- %F\n", c->fd, &m->rx); rewritehdr(&m->rx, m->rpkt); if(mwrite9p(io, c->fd, m->rpkt) < 0) if(verbose) fprint(2, "%T write error: %r\n"); msgput(m); if(c->inputstalled && c->nmsg < MAXMSG) nbsendp(c->inc, 0); } closeioproc(io); free(c->outq); c->outq = nil; sendp(c->outqdead, nil); }
static void epreader(void *u) { int dfd, rcount, cl, ntries, recov; Areader *a; Channel *c; Packser *pk; Serial *ser; Serialport *p; threadsetname("epreader proc"); a = u; p = a->p; ser = p->s; c = a->c; free(a); qlock(ser); /* this makes the reader wait end of initialization too */ dfd = p->epin->dfd; qunlock(ser); ntries = 0; pk = nil; for(;;) { if (pk == nil) pk = emallocz(sizeof(Packser), 1); Eagain: rcount = read(dfd, pk->b, sizeof pk->b); if(serialdebug > 5) dsprint(2, "%d %#ux%#ux ", rcount, p->data[0], p->data[1]); if(rcount < 0) { if(ntries++ > 100) break; qlock(ser); recov = serialrecover(ser, p, nil, "epreader: bulkin error"); qunlock(ser); if(recov >= 0) goto Eagain; } if(rcount == 0) continue; if(rcount >= ser->inhdrsz) { rcount = cpdata(ser, p, pk->b, pk->b, rcount); if(rcount != 0) { pk->nb = rcount; cl = sendp(c, pk); if(cl < 0) { /* * if it was a time-out, I don't want * to give back an error. */ rcount = 0; break; } } else free(pk); qlock(ser); ser->recover = 0; qunlock(ser); ntries = 0; pk = nil; } } if(rcount < 0) fprint(2, "%s: error reading %s: %r\n", argv0, p->name); free(pk); nbsendp(c, nil); if(p->w4data != nil) chanclose(p->w4data); if(p->gotdata != nil) chanclose(p->gotdata); devctl(ser->dev, "detach"); closedev(ser->dev); }
void reqfree(Req *r) { if(!nbsendp(reqs, r)) free(r); }