Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/service.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/service.c 1990/1210
## diff -e /dev/null /n/bootesdump/1990/1210/sys/src/9/port/service.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#include	"fcall.h"

#define	BUFSIZE	(MAXFDATA+500) 	/* BUG */
typedef struct Buffer Buffer;
struct Buffer
{
	Buffer	*next;
	char	buf[BUFSIZE];
};

struct Servalloc {
	Lock;
	Service *all;
	Service *freel;
	Buffer	*ball;
	Buffer	*bfreel;
} servalloc;


/*
 *  allocate the taks force structures and put them
 *  on the free list
 */
void
serviceinit(void)
{
	Service *s;
	Buffer *b;

	servalloc.all = ialloc(conf.nservice * sizeof(Service), 0);
	servalloc.freel = servalloc.all;
	for(s = servalloc.all; s < &servalloc.all[conf.nservice-1]; s++)
		s->next = s+1;

	servalloc.ball = ialloc(2*conf.nservice * sizeof(Service), 0);
	servalloc.bfreel = servalloc.ball;
	for(b = servalloc.ball; b < &servalloc.ball[2*conf.nservice-1]; b++)
		b->next = b+1;
}

/*
 *  Add a process to a service
 */
static Proc *
reinforce(Service *s)
{
	int i;
	Proc *p;

	/*
	 *  don't start one up if we already have too many,
	 *  return our own process number
	 */
	lock(s);
	if(s->ref == NSTUB){
		unlock(s);
		return u->p;
	}
	s->ref++;
	unlock(s);

	/*
	 *  create it
	 */
	return kproc(s->name, 0, 0);
}

/*
 *  resign from a service
 */
static void
resign(Service *s)
{
	int i;

	print("%lux resigning\n", u->p);
	if(decref(s) == 0){
		print("freeing service\n");
		close(s->inc);
		close(s->outc);
		lock(&servalloc);
		s->next = servalloc.freel;
		servalloc.freel = s;
		unlock(&servalloc);
	}
	pexit(0, 1);
}

/*
 *  Create a service of kernel processes to handle file system requests.
 *  (*doit)() is a function that handles that event.  Service
 *  dynamicly creates new processes (up to MAXTASK) to ensure that 1 process
 *  is always awaiting while others are doing.
 */
void
service(char *name, Chan *cin, Chan *cout, void (*doit)(Chan*, char*, long))
{
	void *a;
	Service *s;
	Buffer *b;
	long n;

	b = 0;

	/*
	 *  allocate a service
	 */
	lock(&servalloc);
	s = servalloc.freel;
	if(s == 0)
		panic("no more services");
	servalloc.freel = s->next;
	unlock(&servalloc);
	memset(s, 0, sizeof(Service));
	if(name==0 || *name==0)
		strcpy(name, "filsys");
	else
		strncpy(s->name, name, sizeof(s->name));
	s->inc = cin;
	s->outc = cout;
	s->die = 0;
	incref(cin);
	incref(cout);

	if(waserror()){
		/*
		 *  tell everyone else to die
		 */
		s->die = 1;

		/*
		 *  wake up the next guy
		 */
		qunlock(&s->alock);

		/*
		 *  free the buffer if we have one
		 */
		if(b){
			lock(&servalloc);
			b->next = servalloc.bfreel;
			servalloc.bfreel = b;
			unlock(&servalloc);
		}
		resign(s);
	}

	/*
	 *  Create the first process in the service.  The
	 *  caller returns.
	 */
	if(reinforce(s)){
		poperror();
		return;
	}

	/*
	 *  first process enters the infinite loop
	 */
	for(;;){
		b = 0;
		qlock(&s->alock);

		/*
		 *  if there's more than 1 process waiting, we're
		 *  superfluous
		 */
		if(s->die || s->alock.head && s->alock.head!=s->alock.tail){
			qunlock(&s->alock);
			resign(s);
		}

		/*
		 *  get a buffer
		 */
		lock(&servalloc);
		b = servalloc.bfreel;
		if(b == 0){
			print("no serv buffers\n");
			unlock(&servalloc);
			continue;
		}
		servalloc.bfreel = b->next;
		unlock(&servalloc);

		/*
		 *  wait for something to happen
		 */
		n = (*devtab[cin->type].read)(cin, b->buf, sizeof(b->buf));
		if(n <= 0)
			error(Ehungup);

		/*
		 *  create a new process if none are waiting to
		 *  take over
		 */
		if(s->alock.head == 0)
			if(reinforce(s) == 0)
				continue;
		qunlock(&s->alock);

		/*
		 *  process an event
		 */
		(*doit)(cout, b->buf, n);

		/*
		 *  release the buffer
		 */
		lock(&servalloc);
		b->next = servalloc.bfreel;
		servalloc.bfreel = b;
		unlock(&servalloc);
	}
}
.
## diffname port/service.c 1991/0828 # deleted
## diff -e /n/bootesdump/1990/1210/sys/src/9/port/service.c /n/bootesdump/1991/0828/sys/src/9/port/service.c
1,222d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].