Example #1
0
  private void callStartExpr(Call call, InputChannel ichannel, Process p, Any root, Any context)
      throws AnyException {
    // The call isn't handled in the conventional sense. This is because
    // we want to *resolve* the arguments w.r.t the current context
    // and *call* the function with the context of the root of the
    // new process's node space,
    // First, try to resolve the call target. We need to do this
    // so we can get it's parameter definitions.
    AbstractInputFunc calledFunc = call.resolveFunc(context, getTransaction());
    if (calledFunc == null) throw new AnyException("Could not resolve function " + call);

    // Note that this is the original fn from the catalog. We want
    // to set the flag in here....
    calledFunc.startUse();

    try {
      // Put the transaction in
      call.setTransaction(getTransaction());

      // Resolve the arguments against the current context
      Map startArgs = call.resolveArgs(context, calledFunc, getTransaction());

      // Put the given input channel and new process on the stack
      startArgs.replaceItem(ServerConstants.ICHANNEL, ichannel);
      startArgs.replaceItem(ServerConstants.PROCESS, p);

      Call.call((Func) calledFunc.cloneAny(), startArgs, root, getTransaction(), calledFunc);
    } finally {
      calledFunc.endUse();
    }
  }
Example #2
0
  public Any exec(Any a) throws AnyException {
    Any processName = EvalExpr.evalFunc(getTransaction(), a, processName_);

    Any processType = EvalExpr.evalFunc(getTransaction(), a, processType_);

    InputChannel inputChannel =
        (InputChannel) EvalExpr.evalFunc(getTransaction(), a, inputChannel_, InputChannel.class);

    OutputChannel outputChannel =
        (OutputChannel) EvalExpr.evalFunc(getTransaction(), a, outputChannel_, OutputChannel.class);

    BooleanI syncExternal =
        (BooleanI) EvalExpr.evalFunc(getTransaction(), a, syncExternal_, BooleanI.class);

    // callOnStart/End are already Call objects, not references
    // so we don't need to resolve them.

    if (processName == null) nullOperand(processName_);

    if (processType == null) nullOperand(processType_);

    Process parent = null;

    if (processType.equals(Process.CHILD)) parent = getTransaction().getProcess();
    else if (!processType.equals(Process.DETACHED)) throw new AnyException("Illegal process type");

    if (inputChannel == null && inputChannel_ != null) nullOperand(inputChannel_);

    if (syncExternal == null && syncExternal_ != null) nullOperand(syncExternal_);

    if (outputChannel == null && outputChannel_ != null) nullOperand(outputChannel_);

    // If no input channel is specified, create a new one.
    if (inputChannel == null)
      inputChannel = new AnyChannel(new FIFO(0, ChannelConstants.REFERENCE));
    else inputChannel = inputChannel.getUnderlyingChannel();

    // Create the new process's node space
    BasicProcess.RootMap root = new BasicProcess.RootMap();

    Transaction t = new PrimaryTransaction();

    EventDispatcher ed = new EventDispatcher();
    ed.addEventListener(InvokeService.makeInvokeService(EventConstants.INVOKE_SVC, t, root));

    ed.addEventListener(new DispatchListener(root, t));

    // ExceptionHandler eh = new ExceptionToStream(System.out);
    ExceptionHandler eh = new ExceptionToFunc();

    UserProcess p =
        new UserProcess(
            processName, inputChannel, outputChannel, eh, t, root, ed, parent, callOnEnd_);
    root.setProcess(p);

    // If the process will be 'shared' by other threads (such as
    // JMS asynchronous listeners or any threading model behind
    // client code using AbstractPlugin) then this operand must
    // be set to true.
    // The object these threads synchronize on must, of course,
    // be unique to the new process, so make something new.
    if (syncExternal != null && syncExternal.getValue()) p.setSync(new AnyObject());

    // If there's a start call then run it now in the
    // spawning process's thread but in the spawned
    // process's node space
    if (callOnStart_ != null) {
      Call callOnStart = (Call) callOnStart_.cloneAny();
      callStartExpr(callOnStart, inputChannel, p, root, a);
    }

    // Pass on caller's privilege levels
    Process currProc = getTransaction().getProcess();

    // Just for server startup main() currProc can be null
    if (currProc != null) {
      p.setRealPrivilegeLevel(currProc.getRealPrivilegeLevel());
      p.setEffectivePrivilegeLevel(currProc.getEffectivePrivilegeLevel());

      // Start the new process's thread. If there is no calling
      // process then we assume this class is being run from
      // code, not script, so in case that code has any concurrency
      // issues we expect it to call startThread().
      p.startThread();
    }

    return p;
  }