UTF8 *pool_alloc_lbuf(__in const UTF8 *tag, __in const UTF8 *file, const int line) { if (mudconf.paranoid_alloc) { pool_check(tag, file, line); } UTF8 *p; POOLFTR *pf; POOLHDR *ph = (POOLHDR *)pools[POOL_LBUF].free_head; if ( ph && ph->magicnum == pools[POOL_LBUF].poolmagic) { p = (UTF8 *)(ph + 1); pf = (POOLFTR *)(p + LBUF_SIZE); pools[POOL_LBUF].free_head = ph->nxtfree; // Check for corrupted footer, just report and fix it. // if (pf->magicnum != pools[POOL_LBUF].poolmagic) { pool_err(T("BUG"), LOG_ALWAYS, POOL_LBUF, tag, ph, T("Alloc"), T("corrupted buffer footer"), file, line); pf->magicnum = pools[POOL_LBUF].poolmagic; } } else { if (ph) { // Header is corrupt. Throw away the freelist and start a new // one. pool_err(T("BUG"), LOG_ALWAYS, POOL_LBUF, tag, ph, T("Alloc"), T("corrupted buffer header"), file, line); // Start a new free list and record stats. // pools[POOL_LBUF].free_head = NULL; pools[POOL_LBUF].num_lost += (pools[POOL_LBUF].tot_alloc - pools[POOL_LBUF].num_alloc); pools[POOL_LBUF].tot_alloc = pools[POOL_LBUF].num_alloc; } ph = NULL; try { ph = reinterpret_cast<POOLHDR *>(new char[LBUF_SIZE + sizeof(POOLHDR) + sizeof(POOLFTR)]); } catch (...) { ; // Nothing. } if (NULL == ph) { ISOUTOFMEMORY(ph); return NULL; } p = (UTF8 *)(ph + 1); pf = (POOLFTR *)(p + LBUF_SIZE); // Initialize. // ph->next = pools[POOL_LBUF].chain_head; ph->nxtfree = NULL; ph->magicnum = pools[POOL_LBUF].poolmagic; ph->pool_size = LBUF_SIZE; pf->magicnum = pools[POOL_LBUF].poolmagic; *((unsigned int *)p) = pools[POOL_LBUF].poolmagic; pools[POOL_LBUF].chain_head = ph; pools[POOL_LBUF].max_alloc++; } ph->u.buf_tag = tag; pools[POOL_LBUF].tot_alloc++; pools[POOL_LBUF].num_alloc++; if ( (LOG_ALLOCATE & mudconf.log_options) && mudstate.logging == 0 && start_log(T("DBG"), T("ALLOC"))) { Log.tinyprintf(T("Alloc[%d] (tag %s) in %s line %d buffer at %p. (%s)"), LBUF_SIZE, tag, file, line, ph, mudstate.debug_cmd); end_log(); } // If the buffer was modified after it was last freed, log it. // unsigned int *pui = (unsigned int *)p; if (*pui != pools[POOL_LBUF].poolmagic) { pool_err(T("BUG"), LOG_PROBLEMS, POOL_LBUF, tag, ph, T("Alloc"), T("buffer modified after free"), file, line); } *pui = 0; return p; }
// --------------------------------------------------------------------------- // setup_que: Set up a queue entry. // static BQUE *setup_que ( dbref executor, dbref caller, dbref enactor, int eval, char *command, int nargs, char *args[], reg_ref *sargs[] ) { // Can we run commands at all? // if (Halted(executor)) { return NULL; } // Make sure executor can afford to do it. // int a = mudconf.waitcost; if (mudconf.machinecost && RandomINT32(0, mudconf.machinecost-1) == 0) { a++; } if (!payfor(executor, a)) { notify(Owner(executor), "Not enough money to queue command."); return NULL; } // Wizards and their objs may queue up to db_top+1 cmds. Players are // limited to QUEUE_QUOTA. -mnp // a = QueueMax(Owner(executor)); if (a_Queue(Owner(executor), 1) > a) { a_Queue(Owner(executor), -1); notify(Owner(executor), "Run away objects: too many commands queued. Halted."); halt_que(Owner(executor), NOTHING); // Halt also means no command execution allowed. // s_Halted(executor); return NULL; } // We passed all the tests. // // Calculate the length of the save string. // size_t tlen = 0; static size_t nCommand; static size_t nLenEnv[NUM_ENV_VARS]; if (command) { nCommand = strlen(command) + 1; tlen = nCommand; } if (nargs > NUM_ENV_VARS) { nargs = NUM_ENV_VARS; } for (a = 0; a < nargs; a++) { if (args[a]) { nLenEnv[a] = strlen(args[a]) + 1; tlen += nLenEnv[a]; } } // Create the qeue entry and load the save string. // BQUE *tmp = alloc_qentry("setup_que.qblock"); tmp->comm = NULL; char *tptr = tmp->text = (char *)MEMALLOC(tlen); ISOUTOFMEMORY(tptr); if (command) { memcpy(tptr, command, nCommand); tmp->comm = tptr; tptr += nCommand; } for (a = 0; a < nargs; a++) { if (args[a]) { memcpy(tptr, args[a], nLenEnv[a]); tmp->env[a] = tptr; tptr += nLenEnv[a]; } else { tmp->env[a] = NULL; } } for ( ; a < NUM_ENV_VARS; a++) { tmp->env[a] = NULL; } if (sargs) { for (a = 0; a < MAX_GLOBAL_REGS; a++) { tmp->scr[a] = sargs[a]; if (sargs[a]) { RegAddRef(sargs[a]); } } } else { for (a = 0; a < MAX_GLOBAL_REGS; a++) { tmp->scr[a] = NULL; } } // Load the rest of the queue block. // tmp->executor = executor; tmp->IsTimed = false; tmp->sem = NOTHING; tmp->attr = 0; tmp->enactor = enactor; tmp->caller = caller; tmp->eval = eval; tmp->nargs = nargs; return tmp; }