Exemple #1
0
/*
 *  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;
}
Exemple #2
0
/*
 *  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 */
}
Exemple #3
0
/*
 *  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 */
}
Exemple #4
0
Fichier : qio.c Projet : 8l/inferno
/*
  *  call error if iallocb fails
 */
Block*
allocb(int size)
{
	Block *b;

	b = iallocb(size);
	if(b == 0)
		exhausted("allocb");
	return b;
}
Exemple #5
0
/*
 *  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;
}
Exemple #6
0
/**
 *  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
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}