## 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
|