summaryrefslogtreecommitdiff
path: root/server/class.c
diff options
context:
space:
mode:
authorGravatar John Kohl <jtkohl@mit.edu>1987-03-19 09:08:44 +0000
committerGravatar John Kohl <jtkohl@mit.edu>1987-03-19 09:08:44 +0000
commit6dcaf2ad4b1ef15c76f7f880326ef09fdc54aea9 (patch)
treedd29ab26c0b4e7312cd71b6b116f3d8dba4a60c8 /server/class.c
parent866c40f032a2786942b6cedc842c64edd68b4444 (diff)
All functions, minimal testing establishes it works for at least some
cases
Diffstat (limited to 'server/class.c')
-rw-r--r--server/class.c157
1 files changed, 108 insertions, 49 deletions
diff --git a/server/class.c b/server/class.c
index 43246ce..48d7d65 100644
--- a/server/class.c
+++ b/server/class.c
@@ -1,55 +1,60 @@
-/* Copyright (c) 1987 Massachusetts Institute of Technology */
-
-/*
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains functions for the Zephyr server class manager subsystem.
+ *
+ * Created by: John T. Kohl
+ *
* $Source$
- * $Header$
+ * $Author$
+ *
+ * Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, see the file
+ * "mit-copyright.h".
*/
+#include <zephyr/mit-copyright.h>
+
#ifndef lint
-static char *rcsid_cm_c = "$Header$";
+static char rcsid_cm_c[] = "$Header$";
#endif lint
-#include <zephyr/mit-copyright.h>
#include <zephyr/zephyr.h>
#include "zserver.h"
/*
* Class manager subsystem.
+ *
+ *
* external functions are:
+ *
* Code_t cm_register(client, class)
+ *
* Code_t cm_deregister(client, class)
- * struct qelem *cm_lookup(class)
+ *
+ * ZClientList_t *cm_lookup(class)
* ZClientDesc_t *client;
* char *class;
*/
/* Private variables */
-typedef struct _ZClientList_t {
- struct _ZClientList_t *q_forw;
- struct _ZClientList_t *q_back;
- ZClientDesc_t *client;
-} ZClientList_t;
-
-typedef struct _ZClass_t {
- struct _ZClass_t *q_forw;
- struct _ZClass_t *q_back;
- char *classname;
- ZClientList_t *clientlist;
-} ZClass_t;
-
-
-#define NULLZCT ((ZClass_t *) 0)
-#define NULLZCDT ((ZClientDesc_t *) 0)
-#define NULLZCLT ((ZClientList_t *) 0)
-
#define EMPTY_CLASS 2000
-#define HSHSIZ 8192
-#define HSHMUL 243
+#define HASHSIZE 511
+#define HASHMUL 243
static ZClass_t *class_bucket[511];
/* private routines */
+static int hash(string)
+char *string;
+{
+ register int hval = 0;
+ register char *cp = string;
+
+ while (*cp)
+ hval = (hval + (*cp++) * HASHMUL) % HASHSIZE;
+ return(hval);
+}
+
static ZClass_t *class_alloc(class)
char *class;
{
@@ -64,6 +69,13 @@ char *class;
return(ptr);
}
+static void free_class(ptr)
+ZClass_t *ptr;
+{
+ free(ptr->classname);
+ free(ptr);
+}
+
static ZClientList_t *client_alloc(client)
ZClientDesc_t *client;
{
@@ -83,9 +95,12 @@ ZClientDesc_t *client;
if ((listp = client_alloc(client)) == NULLZCLT)
return(ZERR_UNIX);
- if (ptr->clientlist == NULLZCLT)
- ptr->clientlist = listp;
- else
+
+ if (ptr->clientlist == NULLZCLT) {
+ listp->q_forw = listp;
+ listp->q_back = listp;
+ ptr->clientlist = listp;
+ } else
insque(listp, ptr->clientlist);
return(ZERR_NONE);
}
@@ -98,7 +113,7 @@ ZClientDesc_t *client;
register ZClientList_t *listp2;
if (listp->client == client) { /* found him */
- if (listp->q_forw = listp) { /* this is the only elem on this queue */
+ if (listp->q_forw == listp) { /* this is the only elem on this queue */
ptr->clientlist = NULLZCLT;
free(listp);
return(EMPTY_CLASS);
@@ -112,7 +127,7 @@ ZClientDesc_t *client;
for (listp2 = listp->q_forw; listp2 != listp; listp2 = listp2->q_forw)
/* walk down list, looking for him */
if (listp2->client == client) {
- reqmue(listp);
+ remque(listp);
free(listp);
return(ZERR_NONE);
}
@@ -135,23 +150,24 @@ char *class;
if ((ptr = class_alloc(class)) == NULLZCT)
return(ZERR_UNIX);
+ ptr->q_forw = ptr;
+ ptr->q_back = ptr;
class_bucket[hashval] = ptr;
return(insert_client(ptr, client));
} else if (!strcmp(ptr->classname, class)) /* match! */
return(insert_client(ptr, client));
else {
- for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw) {
- /* walk down the list, looking for a match */
- if (!strcmp(ptr2->classname, class))
- return(insert_client(ptr2, client));
- }
- if (ptr2 = ptr) { /* fell off the end, no match */
- if ((ptr2 = class_alloc(class)) == NULLZCT)
- return(ZERR_UNIX);
- insque(ptr2, ptr); /* insert new class into hash bucket */
+ for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw)
+ /* walk down the list, looking for a match */
+ if (!strcmp(ptr2->classname, class))
return(insert_client(ptr2, client));
- }
+
+ /* fell off the end, no match */
+ if ((ptr2 = class_alloc(class)) == NULLZCT)
+ return(ZERR_UNIX);
+ insque(ptr2, ptr); /* insert new class into hash bucket */
+ return(insert_client(ptr2, client));
}
}
@@ -167,20 +183,63 @@ char *class;
/* no such class to deregister */
return(ZERR_S_BADASSOC);
if (!strcmp(ptr->classname, class)) { /* match! */
- retval = remove_client(ptr, client);
- /* handle retval here*/
- ptr2 = ptr;
+ if (remove_client(ptr, client) == EMPTY_CLASS) {
+ /* careful here, we need to remove it and adjust the pointer to
+ the next element unless this is the only one */
+ if (ptr = ptr->q_forw) {
+ /* garbage collect this bucket */
+ free_class(ptr);
+ class_bucket[hashval] = NULLZCT;
+ } else {
+ /* adjust pointer and garbage collect */
+ class_bucket[hashval] = ptr->q_forw;
+ remque(ptr);
+ free_class(ptr);
+ }
+ }
+ return(ZERR_NONE);
}
else {
for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw) {
/* walk down the list, looking for a match */
if (!strcmp(ptr2->classname, class)) {
- retval = remove_client(ptr2, client);
- /* handle it here too */
+ if ((retval = remove_client(ptr2, client)) == EMPTY_CLASS) {
+ /* here ptr2 is never pointing to class_bucket[hashval],
+ so we don't worry about freeing the bucket */
+ remque(ptr2);
+ free_class(ptr2);
+ return(ZERR_NONE);
+ }
+ /* if not EMPTY_CLASS, it's either ZERR_S_BADASSOC (not found)
+ or ZERR_NONE (found and removed), so break */
break;
}
}
- /* fell off, error */
- return(ZERR_S_BADASSOC);
+
+ /* fell off: either client not found or client found
+ and removed, retval contains the result */
+
+ return(retval);
+ }
+}
+
+ZClientList_t *cm_lookup(class)
+char *class;
+{
+ register ZClass_t *ptr, *ptr2;
+ int hashval = hash(class);
+
+ if ((ptr = class_bucket[hashval]) == NULLZCT)
+ return(NULLZCLT); /* no such class */
+ else if (!strcmp(ptr->classname, class))
+ return(ptr->clientlist);
+ else { /* go search the list for the class */
+ for (ptr2 = ptr->q_forw; ptr2 != ptr; ptr2 = ptr2->q_forw) {
+ /* walk down the list, looking for a match */
+ if (!strcmp(ptr2->classname, class))
+ return(ptr2->clientlist);
+ }
+ /* fell off the end */
+ return(NULLZCLT);
}
}