archie/prospero/lib/pfs/oballoc.c
2024-05-27 16:13:40 +02:00

140 lines
3.8 KiB
C

/*
* Copyright (c) 1992, 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>
*/
#include <usc-license.h>
#include <stdio.h>
#include <stdlib.h> /* For malloc and free */
#include <pfs.h>
static P_OBJECT lfree = NULL;
int p_object_count = 0;
int p_object_max = 0;
/*
* oballoc - allocate and initialize p_object structure
*
* OBALLOC returns a pointer to an initialized structure of type
* P_OBJECT. If it is unable to allocate such a structure, it
* signals out_of_memory();
*/
P_OBJECT
oballoc(void)
{
P_OBJECT ob;
p_th_mutex_lock(p_th_mutexOBALLOC);
if(lfree) {
ob = lfree;
lfree = lfree->next;
}
else {
ob = (P_OBJECT) malloc(sizeof(P_OBJECT_ST));
if (!ob) out_of_memory();
p_object_max++;
}
p_object_count++;
p_th_mutex_unlock(p_th_mutexOBALLOC);
/* Initialize and fill in default values */
#ifdef ALLOCATOR_CONSISTENCY_CHECK
ob->consistency = INUSE_PATTERN;
#endif
ob->version = 0; /* version is always zero. */
ob->flags = 0; /* no flags set */
ob->inc_native = VDIN_UNINITIALIZED; /* don't write out object until this
is reset. Used only on server. */
ob->magic_no = 0L; /* zero means unset */
ob->acl = NULL; /* */
ob->exp = 0;
ob->ttl = 0;
ob->last_ref = 0;
ob->forward = NULL;
ob->backlinks = NULL;
ob->attributes = NULL;
ob->links = NULL;
ob->ulinks = NULL;
ob->native_mtime = 0;
ob->shadow_file = NULL; /* used only on server.*/
ob->status = DQ_INACTIVE; /* used only in client mode. */
ob->dqs = NULL; /* ditto */
ob->statbuf = NULL; /* Used only on server */
ob->app.ptr = NULL; /* On every architecture I ever heard of, ob->
app.flg is now 0 too */
ob->previous = NULL;
ob->next = NULL;
return(ob);
}
static void (*obappfreefunc)(P_OBJECT) = NULL;
/*
* Specify which special freeing function (if any) to be used to free the
* app.ptr member of the P_OBJECT structure, if set.
*/
void
obappfree(void (* appfreefunc)(P_OBJECT))
{
obappfreefunc = appfreefunc;
}
/*
* obfree - free a P_OBJECT structure
*
* OBFREE takes a pointer to a P_OBJECT structure and adds it to
* the free list for later reuse.
*/
void
obfree(P_OBJECT ob)
{
#ifdef ALLOCATOR_CONSISTENCY_CHECK
assert(ob->consistency == INUSE_PATTERN);
ob->consistency = FREE_PATTERN;
#endif
if(ob->acl) aclfree(ob->acl); ob->acl = NULL;
if(ob->forward) { vllfree(ob->forward); ob->forward = NULL;}
if(ob->backlinks) { vllfree(ob->backlinks); ob->backlinks = NULL;}
if(ob->attributes) { atlfree(ob->attributes); ob->attributes = NULL;}
if(ob->links) { vllfree(ob->links); ob->links = NULL; }
if(ob->ulinks) { vllfree(ob->ulinks); ob->ulinks = NULL; }
if(ob->shadow_file) {stfree(ob->shadow_file); ob->shadow_file = NULL;}
if(ob->statbuf) {stfree(ob->statbuf); ob->statbuf = NULL;}
/* If ob->dqs signal a memory leak. */
if(obappfreefunc && ob->app.ptr) {
(*obappfreefunc)(ob->app.ptr);
ob->app.ptr = NULL;
}
p_th_mutex_lock(p_th_mutexOBALLOC);
ob->next = lfree;
ob->previous = NULL;
lfree = ob;
p_object_count--;
p_th_mutex_unlock(p_th_mutexOBALLOC);
}
/*
* oblfree - free a P_OBJECT structure list
*
* OBLFREE takes a pointer to a P_OBJECT structure frees it and any linked
* P_OBJECT structures. It is used to free an entire list of P_OBJECT
* structures.
*/
void
oblfree(P_OBJECT ob)
{
P_OBJECT nxt;
while(ob != NULL) {
nxt = ob->next;
obfree(ob);
ob = nxt;
}
}