diff options
Diffstat (limited to 'cpukit/httpd/h.c')
-rw-r--r-- | cpukit/httpd/h.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/cpukit/httpd/h.c b/cpukit/httpd/h.c new file mode 100644 index 0000000000..ed7a4553eb --- /dev/null +++ b/cpukit/httpd/h.c @@ -0,0 +1,171 @@ +/* + * h.c -- Handle allocation module + * + * Copyright (c) GoAhead Software Inc., 1995-1999. All Rights Reserved. + * See the file "license.txt" for usage and redistribution license requirements + */ + +/******************************** Description *********************************/ + +/* + * This module provides a simple API to allocate and free handles + * It maintains a dynamic array of pointers. These usually point to + * per-handle structures. + */ + +/********************************* Includes ***********************************/ + +#if UEMF + #include "uemf.h" +#else + #include "basic/basicInternal.h" +#endif + +/********************************** Defines ***********************************/ +/* + * The handle list stores the length of the list and the number of used + * handles in the first two words. These are hidden from the caller by + * returning a pointer to the third word to the caller + */ + +#define H_LEN 0 /* First entry holds length of list */ +#define H_USED 1 /* Second entry holds number of used */ +#define H_OFFSET 2 /* Offset to real start of list */ + +#define H_INCR 16 /* Grow handle list in chunks this size */ + +/*********************************** Code *************************************/ +/* + * Allocate a new file handle. On the first call, the caller must set the + * handle map to be a pointer to a null pointer. *map points to the second + * element in the handle array. + */ + +int hAlloc(void ***map) +{ + int *mp; + int handle, len, memsize, incr; + + a_assert(map); + + if (*map == NULL) { + incr = H_INCR; + memsize = (incr + H_OFFSET) * sizeof(void**); + if ((mp = (int*) balloc(B_L, memsize)) == NULL) { + return -1; + } + memset(mp, 0, memsize); + mp[H_LEN] = incr; + mp[H_USED] = 0; + *map = (void**) &mp[H_OFFSET]; + } else { + mp = &((*(int**)map)[-H_OFFSET]); + } + + len = mp[H_LEN]; + +/* + * Find the first null handle + */ + if (mp[H_USED] < mp[H_LEN]) { + for (handle = 0; handle < len; handle++) + if (mp[handle+H_OFFSET] == 0) { + mp[H_USED]++; + return handle; + } + } else { + handle = len; + } + +/* + * No free handle so grow the handle list. Grow list in chunks of H_INCR. + */ + len += H_INCR; + memsize = (len + H_OFFSET) * sizeof(void**); + if ((mp = (int*) brealloc(B_L, (void*) mp, memsize)) == NULL) { + return -1; + } + *map = (void**) &mp[H_OFFSET]; + mp[H_LEN] = len; + memset(&mp[H_OFFSET + len - H_INCR], 0, sizeof(int*) * H_INCR); + mp[H_USED]++; + return handle; +} + +/******************************************************************************/ +/* + * Free a handle. This function returns the value of the largest + * handle in use plus 1, to be saved as a max value. + */ + +int hFree(void ***map, int handle) +{ + int *mp; + int len; + + a_assert(map); + mp = &((*(int**)map)[-H_OFFSET]); + a_assert(mp[H_LEN] >= H_INCR); + + a_assert(mp[handle + H_OFFSET]); + a_assert(mp[H_USED]); + mp[handle + H_OFFSET] = 0; + if (--(mp[H_USED]) == 0) { + bfree(B_L, (void*) mp); + *map = NULL; + } + +/* + * Find the greatest handle number in use. + */ + if (*map == NULL) { + handle = -1; + } else { + len = mp[H_LEN]; + if (mp[H_USED] < mp[H_LEN]) { + for (handle = len - 1; handle >= 0; handle--) { + if (mp[handle + H_OFFSET]) + break; + } + } else { + handle = len; + } + } + return handle + 1; +} + +/******************************************************************************/ +/* + * Allocate an entry in the halloc array. + */ + +int hAllocEntry(void ***list, int *max, int size) +{ + char_t *cp; + int id; + + a_assert(list); + a_assert(max); + + if ((id = hAlloc((void***) list)) < 0) { + return -1; + } + + if (size > 0) { + if ((cp = balloc(B_L, size)) == NULL) { + hFree(list, id); + return -1; + } + a_assert(cp); + memset(cp, 0, size); + + (*list)[id] = (void*) cp; + } + + if (id >= *max) { + *max = id + 1; + } + return id; +} + +/******************************************************************************/ |