gs_call.c

Go to the documentation of this file.
00001 
00006 /* $Id: gs_call.c,v 1.5 2007/03/05 21:58:28 seymour Exp $ */
00007 /* $UTK_Copyright: $ */
00008 
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 
00013 #include "idl_export.h"
00014 #include "grpc.h"
00015 #include "translate.h"
00016 #include "idl_request.h"
00017 
00018 /* Function prototypes */
00019 IDL_VPTR gs_call_common(int, IDL_VPTR*, int);
00020 
00031 IDL_VPTR
00032 gs_call(int argc, IDL_VPTR* argv_idl)
00033 {
00034   return gs_call_common(argc, argv_idl, TRUE);
00035 }
00036 
00046 IDL_VPTR
00047 gs_call_async(int argc, IDL_VPTR* argv_idl)
00048 {
00049   return gs_call_common(argc, argv_idl, FALSE);
00050 }
00051 
00064 IDL_VPTR 
00065 gs_call_common(int argc, IDL_VPTR* argv_idl, int blocking)
00066 {
00067   int                      n;
00068   grpc_sessionid_t         req_id;
00069   char*                    fname;
00070   char*                    nickname;
00071   gs_problem_t*            pd;
00072   grpc_arg_stack*          argstack;
00073   gs_argument_t*           argp;
00074   grpc_error_t             retval;
00075   grpc_function_handle_t*  handle;
00076 
00077   /* 
00078    * Obtain the problem name to be invoked, 
00079    * and peel off "()" of the name if necessary.
00080    */
00081   fname    = IDL_VarGetString(argv_idl[0]);
00082   nickname = strdup(fname);
00083 
00084   if(!nickname) {
00085     IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: strdup failed!");
00086     return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
00087   }
00088 
00089   if(trunc_fname(nickname) < 0) {
00090     IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: invalid problem name!");
00091     free(nickname);
00092     return IDL_GettmpLong(GRPC_FUNCTION_NOT_FOUND);
00093   }
00094 
00095   /* Initialize GridRPC system */
00096   retval = grpc_initialize(NULL);
00097   if((retval != GRPC_NO_ERROR) && (retval != GRPC_ALREADY_INITIALIZED)) {
00098     IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: cannot initialize!");
00099     return IDL_GettmpLong(grpc_errno);
00100   }
00101 
00102   grpc_set_client_major("COL");
00103 
00104   /* Create its GridRPC handle */
00105   handle = (grpc_function_handle_t*)malloc(sizeof(grpc_function_handle_t));
00106 
00107   if(!handle) {
00108     IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, "Error: malloc failed!");
00109     free(nickname);
00110     return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
00111   }
00112 
00113   IDL_TimerBlock(IDL_TRUE);
00114   retval = grpc_function_handle_default(handle, nickname);
00115   IDL_TimerBlock(IDL_FALSE);
00116 
00117   free(nickname);
00118 
00119   /* Verify the returned handle */
00120   if(retval != GRPC_NO_ERROR) {
00121     IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
00122         "Error: failure to create grpc handle!");
00123     free(handle);
00124     return IDL_GettmpLong(grpc_errno);
00125   }
00126 
00127   pd = handle->problem_desc;
00128   if(!pd) {
00129     IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
00130           "Error: empty problem description!");
00131     grpc_function_handle_destruct(handle);
00132     free(handle);
00133     return IDL_GettmpLong(grpc_errno);
00134   }
00135   
00136   /* Time to fill in the pd->arglist */
00137   convert_idl(pd, argv_idl+1);
00138 
00139   /* Create GridSolve arg stack */
00140   n = argc - 1;
00141   if((argstack = grpc_arg_stack_new(n)) == NULL) {
00142     IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
00143           "Error: failure to create arg stack!");
00144     grpc_function_handle_destruct(handle);
00145     free(handle);
00146     return IDL_GettmpLong(grpc_errno);
00147   }
00148 
00149   for(argp = pd->arglist; argp!=NULL; argp=argp->next) {
00150     if(argp->inout != GS_WORKSPACE) {
00151       if(grpc_arg_stack_push_arg(argstack, argp->data) < 0) {
00152         IDL_Message(IDL_M_GENERIC,IDL_MSG_INFO,
00153             "Error: failure to push an arg to stack!");
00154         grpc_arg_stack_destruct(argstack);
00155         grpc_function_handle_destruct(handle);
00156         free(handle);
00157         return IDL_GettmpLong(grpc_errno);
00158       }
00159     }
00160   }
00161 
00162   /* do some checking of the argument sizes before submitting */
00163 
00164   if(gs_sender_compute_arg_sizes(NULL, argstack->args, pd, GS_CALL_FROM_C, 'c') == 0) {
00165     int err_flag, saw_ws, i;
00166     char msg[2048];
00167 
00168     err_flag = 0;
00169     saw_ws = 0;
00170 
00171     /* start idx at 1 to skip the function name arg */
00172     i = 1;
00173 
00174     for(argp = pd->arglist; argp!=NULL; argp=argp->next) {
00175       if(argp->inout != GS_WORKSPACE) {
00176         char *src;
00177    
00178         IDL_ENSURE_SIMPLE(argv_idl[i]);
00179    
00180         /* check arg if it's not workspace or varout */
00181 
00182         if((argp->inout == GS_IN) || (argp->inout == GS_INOUT) || 
00183            (argp->inout == GS_OUT))
00184         {
00185           if((argv_idl[i]->flags & IDL_V_ARR) != 0) {
00186             IDL_MEMINT expected, provided;
00187 
00188             IDL_VarGetData(argv_idl[i], &provided, &src, FALSE);  
00189 
00190             /* special case for char matrices, since they are handled as
00191              * a 1-dimensional array of strings.
00192              */
00193             if((argp->datatype == GS_CHAR) && (argp->objecttype == GS_MATRIX))
00194               expected = argp->rows;
00195             else
00196               expected = argp->rows * argp->cols;
00197          
00198             if(provided < expected) {
00199               sprintf(msg, "Argument %s insufficient size.", 
00200                  IDL_VarName(argv_idl[i]));
00201               IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00202               sprintf(msg, "   - Expected %d total elements",
00203                  (int)expected);
00204               IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00205               sprintf(msg, "   - Actual argument contains %d total elements",
00206                  (int)provided);
00207               IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00208 
00209               err_flag++;
00210             }
00211           }
00212         }
00213 
00214         i++;
00215       }
00216       else
00217         saw_ws = 1;
00218     }
00219 
00220     if(err_flag) {
00221       sprintf(msg, "----------------------");
00222       IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00223       sprintf(msg, "%d arguments were in error.", err_flag);
00224       IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00225       sprintf(msg, "Check the calling sequence (using gs_info).");
00226       IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00227       if(saw_ws) {
00228         sprintf(msg, "This service contains WORKSPACE arguments.");
00229         IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00230         sprintf(msg, "Remember to omit them from the IDL call.");
00231         IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO, msg);
00232       }
00233 
00234       grpc_arg_stack_destruct(argstack);
00235       grpc_function_handle_destruct(handle);
00236       free(handle);
00237       return IDL_GettmpLong(GRPC_OTHER_ERROR_CODE);
00238     }
00239   }
00240   else
00241     IDL_Message(IDL_M_GENERIC, IDL_MSG_INFO,
00242        "Warning: couldn't compute arg sizes.. that can't be a good sign!");
00243   
00244   if(blocking) {
00245     /* now make the blocking call */
00246     IDL_TimerBlock(IDL_TRUE);
00247     retval = grpc_call_arg_stack(handle, argstack);
00248     IDL_TimerBlock(IDL_FALSE);
00249 
00250     postproc_argv_c(pd, argv_idl+1);
00251 
00252     grpc_function_handle_destruct(handle);
00253     free(handle);
00254 
00255     if(argstack)
00256       grpc_arg_stack_destruct(argstack);
00257 
00258     return IDL_GettmpLong(retval);
00259   }
00260   else {
00261     /* now make the non-blocking call */
00262     IDL_TimerBlock(IDL_TRUE);
00263     retval = grpc_call_arg_stack_async(handle, &req_id, argstack);
00264     IDL_TimerBlock(IDL_FALSE);
00265 
00266     if(retval ==  GRPC_NO_ERROR) {
00267       /* successfully sumitted */
00268       if(add_req(req_id, pd, n, argv_idl+1) < 0) {
00269         IDL_Message(IDL_M_GENERIC, IDL_MSG_LONGJMP,
00270            "Error: could not add request!");
00271       }
00272     } 
00273     else {
00274       /* failed to submit, free memory */
00275       req_id = -1;
00276 
00277       postproc_argv_c(pd, argv_idl+1); 
00278 
00279       if(handle) {
00280         grpc_function_handle_destruct(handle);
00281         free(handle);
00282       }
00283 
00284       if(argstack)
00285         grpc_arg_stack_destruct(argstack);
00286     }
00287 
00288     return IDL_GettmpLong(req_id);
00289   }
00290 
00291   /* should not reach here */
00292   return IDL_GettmpLong(-1);
00293 }