/* * create a pipe, no streams are created until an open */ static Chan* pipeattach(char *spec) { Pipe *p; Chan *c; c = devattach('|', spec); p = malloc(sizeof(Pipe)); if(p == 0) exhausted("memory"); p->ref = 1; p->q[0] = qopen(Pipeqsize, 0, 0, 0); if(p->q[0] == 0){ free(p); exhausted("memory"); } p->q[1] = qopen(Pipeqsize, 0, 0, 0); if(p->q[1] == 0){ free(p->q[0]); free(p); exhausted("memory"); } lock(&pipealloc); p->path = ++pipealloc.path; unlock(&pipealloc); mkqid(&c->qid, PIPEQID(2*p->path, Qdir), 0, QTDIR); c->aux = p; c->devno = 0; return c; }
/* * Increment the reference count of a network device. * If id < 0, return an unused ether device. */ static int openfile(struct ether *nif, int id) { ERRSTACK(1); struct netfile *f, **fp, **efp; if (id >= 0) { f = nif->f[id]; if (f == 0) error(Enodev); qlock(&f->qlock); qreopen(f->in); f->inuse++; qunlock(&f->qlock); return id; } qlock(&nif->qlock); if (waserror()) { qunlock(&nif->qlock); nexterror(); } efp = &nif->f[nif->nfile]; for (fp = nif->f; fp < efp; fp++) { f = *fp; if (f == 0) { f = kzmalloc(sizeof(struct netfile), 0); if (f == 0) exhausted("memory"); /* since we lock before netifinit (if we ever call that...) */ qlock_init(&f->qlock); f->in = qopen(nif->limit, Qmsg, 0, 0); if (f->in == NULL) { kfree(f); exhausted("memory"); } *fp = f; qlock(&f->qlock); } else { qlock(&f->qlock); if (f->inuse) { qunlock(&f->qlock); continue; } } f->inuse = 1; qreopen(f->in); netown(f, current->user, 0); qunlock(&f->qlock); qunlock(&nif->qlock); poperror(); return fp - nif->f; } error(Enodev); return -1; /* not reached */ }
/* * Increment the reference count of a network device. * If id < 0, return an unused ether device. */ static int openfile(Netif *nif, int id) { Proc *up = externup(); Netfile *f, **fp, **efp; if(id >= 0){ f = nif->f[id]; if(f == 0) error(Enodev); qlock(&f->q); qreopen(f->iq); f->inuse++; qunlock(&f->q); return id; } qlock(&nif->q); if(waserror()){ qunlock(&nif->q); nexterror(); } efp = &nif->f[nif->nfile]; for(fp = nif->f; fp < efp; fp++){ f = *fp; if(f == 0){ f = malloc(sizeof(Netfile)); if(f == 0) exhausted("memory"); f->iq = qopen(nif->limit, Qmsg, 0, 0); if(f->iq == nil){ free(f); exhausted("memory"); } *fp = f; qlock(&f->q); } else { qlock(&f->q); if(f->inuse){ qunlock(&f->q); continue; } } f->inuse = 1; qreopen(f->iq); netown(f, up->user, 0); qunlock(&f->q); qunlock(&nif->q); poperror(); return fp - nif->f; } error(Enodev); return -1; /* not reached */ }
/* * call error if iallocb fails */ Block* allocb(int size) { Block *b; b = iallocb(size); if(b == 0) exhausted("allocb"); return b; }
/* * create a pipe, no streams are created until an open */ static Chan* pipeattach(char *spec) { Pipe *p; Chan *c; c = devattach('|', spec); if(waserror()){ chanfree(c); nexterror(); } p = malloc(sizeof(Pipe)); if(p == 0) exhausted("memory"); p->ref = 1; p->q[0] = qopen(conf.pipeqsize, 0, 0, 0); if(p->q[0] == 0){ free(p); exhausted("memory"); } p->q[1] = qopen(conf.pipeqsize, 0, 0, 0); if(p->q[1] == 0){ qfree(p->q[0]); free(p); exhausted("memory"); } poperror(); lock(&pipealloc); p->path = ++pipealloc.path; unlock(&pipealloc); p->perm = pipedir[Qdata0].perm; mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR); c->aux = p; c->dev = 0; return c; }
/** * Throw an Exhausted exception to indicate that the %arena has been asked to * allocate 'size' bytes of memory and that this exceeds the arena's internal * limit. * * The exception we throw can be caught either as an arena::Exhausted or else * as a SystemException. */ void Arena::exhausted(size_t size) const { struct exhausted : Exhausted, SystemException { exhausted(const Arena& a,size_t n) : SystemException(SYSTEM_EXCEPTION(SCIDB_SE_NO_MEMORY,SCIDB_LE_ARENA_EXHAUSTED) << a << bytes_t(n)) {} const char* what() const throw() { return SystemException::what(); // Use scidb message } }; throw exhausted(*this,size); // Throw an exception }
int newfd(Chan *c) { int i; Fgrp *f = up->env->fgrp; lock(f); for(i=f->minfd; i<f->nfd; i++) if(f->fd[i] == 0) break; if(i >= f->nfd && growfd(f, i) < 0){ unlock(f); exhausted("file descriptors"); return -1; } f->minfd = i + 1; if(i > f->maxfd) f->maxfd = i; f->fd[i] = c; unlock(f); return i; }
static Chan* loopbackattach(char *spec) { Loop *volatile lb; Queue *q; Chan *c; int chan; int dev; dev = 0; if(spec != nil){ dev = atoi(spec); if(dev >= Nloopbacks) error(Ebadspec); } c = devattach('X', spec); if(waserror()){ chanfree(c); nexterror(); } lb = &loopbacks[dev]; qlock(lb); if(waserror()){ lb->ref--; qunlock(lb); nexterror(); } lb->ref++; if(lb->ref == 1){ for(chan = 0; chan < 2; chan++){ lb->link[chan].ci.mode = Trelative; lb->link[chan].ci.a = &lb->link[chan]; lb->link[chan].ci.f = linkintr; lb->link[chan].limit = Loopqlim; q = qopen(lb->link[chan].limit, 0, 0, 0); lb->link[chan].iq = q; if(q == nil){ freelb(lb); exhausted("memory"); } q = qopen(lb->link[chan].limit, 0, 0, 0); lb->link[chan].oq = q; if(q == nil){ freelb(lb); exhausted("memory"); } lb->link[chan].indrop = 1; lb->link[chan].delaynns = Delayn; lb->link[chan].delay0ns = Delay0; } } poperror(); qunlock(lb); poperror(); mkqid(&c->qid, QID(0, Qtopdir), 0, QTDIR); c->aux = lb; c->dev = dev; return c; }