nightmare4_fluffos_v1/
nightmare4_fluffos_v1/bin/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/ChangeLog.old/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/Win32/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/compat/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/compat/simuls/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/include/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/clone/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/command/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/data/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/etc/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/include/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/inherit/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/inherit/master/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/log/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/compiler/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/efuns/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/operators/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/u/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/tmp/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/windows/
nightmare4_fluffos_v1/lib/cfg/
nightmare4_fluffos_v1/lib/cmds/admins/
nightmare4_fluffos_v1/lib/cmds/common/
nightmare4_fluffos_v1/lib/cmds/creators/include/
nightmare4_fluffos_v1/lib/cmds/creators/include/SCCS/
nightmare4_fluffos_v1/lib/cmds/hm/
nightmare4_fluffos_v1/lib/daemon/services/
nightmare4_fluffos_v1/lib/doc/
nightmare4_fluffos_v1/lib/doc/faq/
nightmare4_fluffos_v1/lib/doc/help/classes/
nightmare4_fluffos_v1/lib/doc/help/creators/
nightmare4_fluffos_v1/lib/doc/help/hm/
nightmare4_fluffos_v1/lib/doc/help/players/
nightmare4_fluffos_v1/lib/doc/help/races/
nightmare4_fluffos_v1/lib/doc/help/religion/
nightmare4_fluffos_v1/lib/doc/mudlib/
nightmare4_fluffos_v1/lib/doc/mudlib/cfg/
nightmare4_fluffos_v1/lib/domains/Ylsrim/
nightmare4_fluffos_v1/lib/domains/Ylsrim/adm/
nightmare4_fluffos_v1/lib/domains/Ylsrim/armour/
nightmare4_fluffos_v1/lib/domains/Ylsrim/fish/
nightmare4_fluffos_v1/lib/domains/Ylsrim/meal/
nightmare4_fluffos_v1/lib/domains/Ylsrim/npc/
nightmare4_fluffos_v1/lib/domains/Ylsrim/virtual/
nightmare4_fluffos_v1/lib/domains/Ylsrim/weapon/
nightmare4_fluffos_v1/lib/domains/Ylsrim/xtra/
nightmare4_fluffos_v1/lib/lib/comp/
nightmare4_fluffos_v1/lib/lib/lvs/
nightmare4_fluffos_v1/lib/lib/std/
nightmare4_fluffos_v1/lib/lib/user/
nightmare4_fluffos_v1/lib/news/
nightmare4_fluffos_v1/lib/obj/
nightmare4_fluffos_v1/lib/obj/include/
nightmare4_fluffos_v1/lib/save/
nightmare4_fluffos_v1/lib/save/kills/a/
nightmare4_fluffos_v1/lib/save/kills/b/
nightmare4_fluffos_v1/lib/save/kills/f/
nightmare4_fluffos_v1/lib/save/kills/m/
nightmare4_fluffos_v1/lib/save/kills/q/
nightmare4_fluffos_v1/lib/save/kills/r/
nightmare4_fluffos_v1/lib/secure/cfg/
nightmare4_fluffos_v1/lib/secure/cfg/classes/
nightmare4_fluffos_v1/lib/secure/cfg/races/SCCS/
nightmare4_fluffos_v1/lib/secure/cmds/creators/include/
nightmare4_fluffos_v1/lib/secure/cmds/players/
nightmare4_fluffos_v1/lib/secure/cmds/players/include/
nightmare4_fluffos_v1/lib/secure/daemon/include/
nightmare4_fluffos_v1/lib/secure/lib/
nightmare4_fluffos_v1/lib/secure/lib/include/
nightmare4_fluffos_v1/lib/secure/lib/net/
nightmare4_fluffos_v1/lib/secure/lib/std/
nightmare4_fluffos_v1/lib/secure/obj/
nightmare4_fluffos_v1/lib/secure/obj/include/
nightmare4_fluffos_v1/lib/secure/save/
nightmare4_fluffos_v1/lib/secure/save/boards/
nightmare4_fluffos_v1/lib/secure/save/votes/
nightmare4_fluffos_v1/lib/spells/
nightmare4_fluffos_v1/lib/verbs/admins/include/
nightmare4_fluffos_v1/lib/verbs/common/
nightmare4_fluffos_v1/lib/verbs/common/include/
nightmare4_fluffos_v1/lib/verbs/creators/
nightmare4_fluffos_v1/lib/verbs/creators/include/
nightmare4_fluffos_v1/lib/verbs/players/include/SCCS/
nightmare4_fluffos_v1/lib/verbs/rooms/
nightmare4_fluffos_v1/lib/verbs/rooms/include/
nightmare4_fluffos_v1/lib/www/
nightmare4_fluffos_v1/old/
nightmare4_fluffos_v1/old/tools/
nightmare4_fluffos_v1/win32/
/*
 * reclaim.c
 * loops through all variables in all objects looking for the possibility
 * of freeing up destructed objects (that are still hanging around because
 * of references) -- coded by Blackthorn@Genocide Feb. 1993
 */

#include "std.h"
#include "lpc_incl.h"
#include "reclaim.h"
#include "call_out.h"

#define MAX_RECURSION 25

static void gc_mapping (mapping_t *);
static void check_svalue (svalue_t *);

static int cleaned, nested;

static void
check_svalue (svalue_t * v)
{
    register int idx;

    nested++;
    if (nested > MAX_RECURSION) {
        return;
    }
    switch (v->type) {
    case T_OBJECT:
        if (v->u.ob->flags & O_DESTRUCTED) {
            free_svalue(v, "reclaim_objects");
            *v = const0u;
            cleaned++;
        }
        break;
    case T_MAPPING:
        gc_mapping(v->u.map);
        break;
    case T_ARRAY:
    case T_CLASS:
        for (idx = 0; idx < v->u.arr->size; idx++)
            check_svalue(&v->u.arr->item[idx]);
        break;
    case T_FUNCTION:
        {
            svalue_t tmp;
            program_t *prog;

            if (v->u.fp->hdr.owner && (v->u.fp->hdr.owner->flags & O_DESTRUCTED)) {
                if (v->u.fp->hdr.type == (FP_LOCAL | FP_NOT_BINDABLE)) {
                    prog = v->u.fp->hdr.owner->prog;
                    prog->func_ref--;
                    debug(d_flag, ("subtr func ref /%s: now %i\n",
                                prog->filename, prog->func_ref));
                    if (!prog->ref && !prog->func_ref)
                        deallocate_program(prog);
                }
                free_object(&v->u.fp->hdr.owner, "reclaim_objects");
                v->u.fp->hdr.owner = 0;
                cleaned++;
            }

            tmp.type = T_ARRAY;
            if ((tmp.u.arr = v->u.fp->hdr.args))
                check_svalue(&tmp);
            break;
        }
    }
    nested--;
    return;
}

static void
gc_mapping (mapping_t * m)
{
    /* Be careful to correctly handle destructed mapping keys.  We can't
     * just call check_svalue() b/c the hash would be wrong and the '0'
     * element we add would be unreferenceable (in most cases)
     */
    mapping_node_t **prev, *elt;
    int j = m->table_size;

    do {
        prev = m->table + j;
        while ((elt = *prev)) {
            if (elt->values[0].type == T_OBJECT) {
                if (elt->values[0].u.ob->flags & O_DESTRUCTED) {
                    free_object(&elt->values[0].u.ob, "gc_mapping");
		    elt->values[0].u.ob = 0;
                    /* found one, do a map_delete() */
                    if (!(*prev = elt->next) && !m->table[j])
                        m->unfilled++;
                    cleaned++;
                    m->count--;
                    total_mapping_nodes--;
                    total_mapping_size -= sizeof(mapping_node_t);
                    free_node(m, elt);
                    continue;
                }
            } else {
                /* in case the key is a mapping or something */
                check_svalue(elt->values);
            }
            check_svalue(elt->values+1);
            prev = &(elt->next);
        }
    } while (j--);
}

int reclaim_objects()
{
    int i;
    object_t *ob;

    reclaim_call_outs();

    cleaned = nested = 0;
    for (ob = obj_list; ob; ob = ob->next_all)
        if (ob->prog)
            for (i = 0; i < ob->prog->num_variables_total; i++)
                check_svalue(&ob->variables[i]);
    
    return cleaned;
}