Functions

gs_call.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "idl_export.h"
#include "grpc.h"
#include "translate.h"
#include "idl_request.h"
Include dependency graph for gs_call.c:

Go to the source code of this file.

Functions

IDL_VPTR gs_call_common (int, IDL_VPTR *, int)
IDL_VPTR gs_call (int argc, IDL_VPTR *argv_idl)
IDL_VPTR gs_call_async (int argc, IDL_VPTR *argv_idl)

Function Documentation

IDL_VPTR gs_call ( int  argc,
IDL_VPTR *  argv_idl 
)

Performs a blocking GridRPC call.

Parameters:
argc -- the number of arguments
argv_idl -- the array of IDL arguments passed in
Returns:
an IDL variable containing the GridRPC exit status of the call. See the GridRPC documentation for details.

Definition at line 32 of file gs_call.c.

{
  return gs_call_common(argc, argv_idl, TRUE);
}

Here is the call graph for this function:

IDL_VPTR gs_call_async ( int  argc,
IDL_VPTR *  argv_idl 
)

Performs a non-blocking GridRPC call.

Parameters:
argc -- the number of arguments
argv_idl -- the array of IDL arguments passed in
Returns:
the request ID for the submitted job.

Definition at line 47 of file gs_call.c.

{
  return gs_call_common(argc, argv_idl, FALSE);
}

Here is the call graph for this function:

IDL_VPTR gs_call_common ( int  argc,
IDL_VPTR *  argv_idl,
int  blocking 
)

The implementation of nonblocking gs_call_async() call.

This is part of the IDL Client for GridSolve.

Common code for blocking and non-blocking GridRPC calls.

Parameters:
argc -- the number of arguments
argv_idl -- the array of IDL arguments passed in
blocking -- if TRUE, this is a blocking request. otherwise, it is a non-blocking request.
Returns:
GridRPC exit status if blocking; request ID if non-blocking.

Definition at line 65 of file gs_call.c.

{
  int                      n;
  grpc_sessionid_t         req_id;
  char*                    fname;
  char*                    nickname;
  gs_problem_t*            pd;
  grpc_arg_stack*          argstack;
  gs_argument_t*           argp;
  grpc_error_t             retval;
  grpc_function_handle_t*  handle;

  /* 
   * Obtain the problem name to be invoked, 
   * and peel off "()" of the name if necessary.
   */
  fname    = IDL_VarGetString(argv_idl[0]);
  nickname = strdup(fname);

  if(!nickname) {
    IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: strdup failed!");
    return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
  }

  if(trunc_fname(nickname) < 0) {
    IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: invalid problem name!");
    free(nickname);
    return IDL_GettmpLong(GRPC_FUNCTION_NOT_FOUND);
  }

  /* Initialize GridRPC system */
  retval = grpc_initialize(NULL);
  if((retval != GRPC_NO_ERROR) && (retval != GRPC_ALREADY_INITIALIZED)) {
    IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: cannot initialize!");
    return IDL_GettmpLong(grpc_errno);
  }

  grpc_set_client_major("COL");

  /* Create its GridRPC handle */
  handle = (grpc_function_handle_t*)malloc(sizeof(grpc_function_handle_t));

  if(!handle) {
    IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: malloc failed!");
    free(nickname);
    return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
  }

  IDL_TimerBlock(IDL_TRUE);
  retval = grpc_function_handle_default(handle, nickname);
  IDL_TimerBlock(IDL_FALSE);

  free(nickname);

  /* Verify the returned handle */
  if(retval != GRPC_NO_ERROR) {
    IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
        "Error: failure to create grpc handle!");
    free(handle);
    return IDL_GettmpLong(grpc_errno);
  }

  pd = handle->problem_desc;
  if(!pd) {
    IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
          "Error: empty problem description!");
    grpc_function_handle_destruct(handle);
    free(handle);
    return IDL_GettmpLong(grpc_errno);
  }
  
  /* Time to fill in the pd->arglist */
  convert_idl(pd, argv_idl+1);

  /* Create GridSolve arg stack */
  n = argc - 1;
  if((argstack = grpc_arg_stack_new(n)) == NULL) {
    IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
          "Error: failure to create arg stack!");
    grpc_function_handle_destruct(handle);
    free(handle);
    return IDL_GettmpLong(grpc_errno);
  }

  for(argp = pd->arglist; argp!=NULL; argp=argp->next) {
    if(argp->inout != GS_WORKSPACE) {
      if(grpc_arg_stack_push_arg(argstack, argp->data) < 0) {
        IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
            "Error: failure to push an arg to stack!");
        grpc_arg_stack_destruct(argstack);
        grpc_function_handle_destruct(handle);
        free(handle);
        return IDL_GettmpLong(grpc_errno);
      }
    }
  }

  /* do some checking of the argument sizes before submitting */

  if(gs_sender_compute_arg_sizes(NULL, argstack->args, pd, GS_CALL_FROM_C, 'c') == 0) {
    int err_flag, saw_ws, i;
    char msg[2048];

    err_flag = 0;
    saw_ws = 0;

    /* start idx at 1 to skip the function name arg */
    i = 1;

    for(argp = pd->arglist; argp!=NULL; argp=argp->next) {
      if(argp->inout != GS_WORKSPACE) {
        char *src;
   
        IDL_ENSURE_SIMPLE(argv_idl[i]);
   
        /* check arg if it's not workspace or varout */

        if((argp->inout == GS_IN) || (argp->inout == GS_INOUT) || 
           (argp->inout == GS_OUT))
        {
          if((argv_idl[i]->flags & IDL_V_ARR) != 0) {
            IDL_MEMINT expected, provided;

            IDL_VarGetData(argv_idl[i], &provided, &src, FALSE);  

            /* special case for char matrices, since they are handled as
             * a 1-dimensional array of strings.
             */
            if((argp->datatype == GS_CHAR) && (argp->objecttype == GS_MATRIX))
              expected = argp->rows;
            else
              expected = argp->rows * argp->cols;
         
            if(provided < expected) {
              sprintf(msg, "Argument %s insufficient size.", 
                 IDL_VarName(argv_idl[i]));
              IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
              sprintf(msg, "   - Expected %d total elements",
                 (int)expected);
              IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
              sprintf(msg, "   - Actual argument contains %d total elements",
                 (int)provided);
              IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);

              err_flag++;
            }
          }
        }

        i++;
      }
      else
        saw_ws = 1;
    }

    if(err_flag) {
      sprintf(msg, "----------------------");
      IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
      sprintf(msg, "%d arguments were in error.", err_flag);
      IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
      sprintf(msg, "Check the calling sequence (using gs_info).");
      IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
      if(saw_ws) {
        sprintf(msg, "This service contains WORKSPACE arguments.");
        IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
        sprintf(msg, "Remember to omit them from the IDL call.");
        IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
      }

      grpc_arg_stack_destruct(argstack);
      grpc_function_handle_destruct(handle);
      free(handle);
      return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
    }
  }
  else
    IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO,
       "Warning: couldn't compute arg sizes.. that can't be a good sign!");
  
  if(blocking) {
    /* now make the blocking call */
    IDL_TimerBlock(IDL_TRUE);
    retval = grpc_call_arg_stack(handle, argstack);
    IDL_TimerBlock(IDL_FALSE);

    postproc_argv_c(pd, argv_idl+1);

    grpc_function_handle_destruct(handle);
    free(handle);

    if(argstack)
      grpc_arg_stack_destruct(argstack);

    return IDL_GettmpLong(retval);
  }
  else {
    /* now make the non-blocking call */
    IDL_TimerBlock(IDL_TRUE);
    retval = grpc_call_arg_stack_async(handle, &req_id, argstack);
    IDL_TimerBlock(IDL_FALSE);

    if(retval ==  GRPC_NO_ERROR) {
      /* successfully sumitted */
      if(add_req(req_id, pd, n, argv_idl+1) < 0) {
        IDL_Message(IDL_M_GENERIC, IDL_MSG_LONGJMP,
           "Error: could not add request!");
      }
    } 
    else {
      /* failed to submit, free memory */
      req_id = -1;

      postproc_argv_c(pd, argv_idl+1); 

      if(handle) {
        grpc_function_handle_destruct(handle);
        free(handle);
      }

      if(argstack)
        grpc_arg_stack_destruct(argstack);
    }

    return IDL_GettmpLong(req_id);
  }

  /* should not reach here */
  return IDL_GettmpLong(-1);
}

Here is the call graph for this function:

Here is the caller graph for this function: