/* * A new plant is constructed. The properties of the factory * should be known upon compile time. They are retrieved from * the signature of the factory definition. */ Plant newPlant(MalBlkPtr mb) { Plant p, plim; MalStkPtr stk; plim = plants + lastPlant; for (p = plants; p < plim && p->factory; p++) ; stk = newGlobalStack(mb->vsize); if (lastPlant == MAXPLANTS || stk == NULL){ if( stk) GDKfree(stk); return 0; } if (p == plim) lastPlant++; p->factory = mb; p->id = plantId++; p->pc = 1; /* where we start */ p->stk = stk; p->stk->blk = mb; p->stk->keepAlive = TRUE; return p; }
MalStkPtr reallocGlobalStack(MalStkPtr old, int cnt) { int k; MalStkPtr s; if (old->stksize > cnt) return old; k = ((cnt / STACKINCR) + 1) * STACKINCR; s = newGlobalStack(k); memcpy(s, old, stackSize(old->stksize)); s->stksize = k; GDKfree(old); return s; }
/* * This is a phtread started function. Here we start the client. We * need to initialize and allocate space for the global variables. * Thereafter it is up to the scenario interpreter to process input. */ void MSserveClient(void *dummy) { MalBlkPtr mb; Client c = (Client) dummy; str msg = 0; if (!isAdministrator(c) && MCinitClientThread(c) < 0) { MCcloseClient(c); return; } /* * A stack frame is initialized to keep track of global variables. * The scenarios are run until we finally close the last one. */ mb = c->curprg->def; if (c->glb == NULL) c->glb = newGlobalStack(MAXGLOBALS + mb->vsize); if (c->glb == NULL) { showException(c->fdout, MAL, "serveClient", MAL_MALLOC_FAIL); c->mode = FINISHCLIENT + 1; /* == RUNCLIENT */ } else { c->glb->stktop = mb->vtop; c->glb->blk = mb; } if (c->scenario == 0) msg = defaultScenario(c); if (msg) { showException(c->fdout, MAL, "serveClient", "could not initialize default scenario"); c->mode = FINISHCLIENT + 1; /* == RUNCLIENT */ GDKfree(msg); } else { do { do { runScenario(c); if (c->mode == FINISHCLIENT) break; resetScenario(c); } while (c->scenario && !GDKexiting()); } while (c->scenario && c->mode != FINISHCLIENT && !GDKexiting()); } /* pre announce our exiting: cleaning up may take a while and we * don't want to get killed during that time for fear of * deadlocks */ MT_exiting_thread(); /* * At this stage we should clean out the MAL block */ freeMalBlk(c->curprg->def); c->curprg->def = 0; if (c->mode > FINISHCLIENT) { if (isAdministrator(c) /* && moreClients(0)==0 */) { if (c->scenario) { exitScenario(c); } } } if (!isAdministrator(c)) MCcloseClient(c); }