/* * The indicated node has failed, find and unavailable any pending * operations. We need to go through outstandingInvokes and aggressively * locate the state that holds our continuation. */ void invokeHandleDown(struct noderecord *nd) { State *state, *nextstate; ISetForEach(allProcesses, state) { if (!isNoOID(state->nsoid)) { nextstate = (State *)OIDFetch(state->nsoid); if (ISNIL(nextstate) || !RESDNT(nextstate->firstThing)) { if (ISNIL(nextstate)) nextstate = stateFetch(state->nsoid, limbo); aggressivelyLocate((Object)nextstate); /* * Because aggressivelyLocate may remove the state from allProcesss * we have to fudge with the index */ if (allProcesses->table[ISetxx_index].key != (int)state) ISetxx_index--; } } else if (!isNoOID(state->nstoid)) { /* * This is an outstanding move, we should do something. */ TRACE(rinvoke, 0, ("A node has failed while a move is outstanding for %s", OIDString(state->nstoid))); makeReady(state); } } ISetNext(); }
void Data::isReady(){ if(eof()){ throw DataException("Stream is closed!"); return; } if(!ready){ makeReady(); } return; }
void handleInvokeRequest(RemoteOpHeader *h, Node srv, Stream str) { Stream newstr; int argc = h->option2, retc = h->option1, fn = h->status, i; Object obj; ConcreteType ct = 0; RemoteOpHeader replyh; int *sp; State *state; anticipateGC(64 * 1024 + 2 * StreamLength(str)); TRACE(rinvoke, 3, ("InvokeRequest received")); /* figure out who we're invoking on */ obj = OIDFetch(h->target); if (!ISNIL(obj)) { ct = CODEPTR(obj->flags); TRACE(rinvoke, 4, ("Target is a %.*s, operation name is %.*s[%d]", ct->d.name->d.items, ct->d.name->d.data, ct->d.opVector->d.data[fn]->d.name->d.items, ct->d.opVector->d.data[fn]->d.name->d.data, argc)); } else { TRACE(rinvoke, 1, ("Invoking %s op %d [%d] -> [%d]", OIDString(h->target), fn, argc, retc)); } if (ISNIL(obj)) { /* * Invoke came here, but we don't know anything about this object. * First find it, then send it the message. */ TRACE(rinvoke, 1, ("Trying to find the object and send it the message")); ct = (ConcreteType)doObjectRequest(replyh.sslocation, &h->targetct, ctct); obj = createStub(ct, getNodeRecordFromSrv(replyh.sslocation), h->target); RewindStream(str); newstr = StealStream(str); findAndSendTo(h->target, newstr); } else if (!RESDNT(obj->flags)) { Node newsrv = getLocFromObj(obj); /* Invoke came here, but the object is elsewhere */ /* First check to see if we think the object is where this invoke came from */ if (SameNode(srv, newsrv) || SameNode(myid, newsrv) || SameNode(limbo, newsrv)) { TRACE(rinvoke, 1, ("Have stub, but points back. Forwarding to limbo")); RewindStream(str); newstr = StealStream(str); findAndSendTo(h->target, newstr); } else { TRACE(rinvoke, 1, ("Forwarding invoke to %s", NodeString(newsrv))); if (forwardMsg(newsrv, h, str) < 0) { RewindStream(str); newstr = StealStream(str); findAndSendTo(h->target, newstr); } } } else if (fakeUnavailable && ((random() % 100) < fakeUnavailable)) { newstr = StealStream(str); sendUnavailableReply(newstr); } else { OID oid; state = newState(obj, ct); OIDRemoveAny((Object)state); ReadOID(&oid, str); OIDInsert(oid, (Object) state); for (sp = (int *)state->sb, i = 0 ; i < 2 * retc ; i++) *sp++ = JNIL; extractNVars(str, argc, sp, &state->ep, &state->et, srv); sp += argc * 2; TRACE(rinvoke, 4, ("Doing upcall on a %.*s", CODEPTR(obj->flags)->d.name->d.items, CODEPTR(obj->flags)->d.name->d.data)); state->sp = (u32)sp; pushBottomAR(state); /* set up the interpreter state */ state->pc = (u32) ct->d.opVector->d.data[fn]->d.code->d.data; dependsOn(state, stateFetch(h->ss, h->sslocation), retc); makeReady(state); } inhibit_gc--; }
void handleInvokeReply(RemoteOpHeader *h, Node srv, Stream str) { State *state; anticipateGC(64 * 1024 + 2 * StreamLength(str)); state = (State *)OIDFetch(h->ss); if (ISNIL(state) || !RESDNT(state->firstThing)) { /* * We probably gc'd this state because we couldn't find any references * to it. Find it and send it this reply. */ Stream newstr; RewindStream(str); newstr = StealStream(str); findAndSendTo(h->ss, newstr); } else { TRACE(rinvoke, 3, ("InvokeReply received")); assert(!ISNIL(state)); assert(RESDNT(state->firstThing)); assert(ISetMember(allProcesses, (int)state)); TRACE(process, 5, ("Resetting nsoid in state %#x", state)); state->nsoid = nooid; state->nstoid = nooid; if (h->status) { TRACE(rinvoke, 0, ("Obsolete remote invocation return code")); h->option1 = 2; } if (h->option1) { /* * We are supposed to propagate a failure. */ TRACE(rinvoke, 1, ("Remote invocation raised %s", h->option1 == 1 ? "failure" : h->option1 == 2 ? "unavailable" : "unknown")); if (!findHandler(state, h->option1 - 1, (Object)JNIL)) { if (!debugInteractively) { state = processDone(state, h->option1); } else { char buf[80]; sprintf(buf, "Remote invocation raised %s", h->option1 == 1 ? "failure" : h->option1 == 2 ? "unavailable" : "unknown"); if (debug(state, buf)) { /* * debug returns 1 when we shouldn't run the state no more. */ state = 0; } } } if (state) makeReady(state); } else if (RESDNT(state->op->flags) && BROKEN(state->op->flags) && isBroken(state->op)) { if (returnToBrokenObject(state)) { /* nothing to do */ } else { makeReady(state); } } else { extractNVars(str, -1, (int *)state->sp, &state->ep, &state->et, srv); makeReady(state); } } TRACE(rinvoke, 4, ("Invoke return handled")); inhibit_gc--; }