Defines | Functions | Variables

gsgrpc.c File Reference

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "portability.h"
#include "grpc.h"
#include "icl_hash.h"
Include dependency graph for gsgrpc.c:

Go to the source code of this file.

Defines

#define ERROR_MAIN
#define TRUE   1
#define FALSE   0
#define va_copy(dst, src)   memcpy (&dst, &src, sizeof(va_list))
#define GS_PORT_DELIM   '/'
#define GS_PROXY_DELIM   '%'
#define GS_MAX_PINGS   5
#define GS_DEFAULT_CACHE_TTL   300
#define GS_DEFAULT_TIME_THRESH   1.0
#define GRPC_CLEAR_ERRORS()
#define GRPC_FAIL_IF_NOT_INITIALIZED(retval)

Functions

static grpc_error_t gs_call_common (grpc_function_handle_t *, grpc_sessionid_t *, gs_va_list *, void **, int)
static grpc_error_t gs_call_common_ft (grpc_function_handle_t *, grpc_sessionid_t *, gs_va_list *, void **, int)
static grpc_error_t grpc_function_handle_common (grpc_function_handle_t *, char *, char *)
static grpc_error_t gs_resubmit_common (int)
static int gs_notify_agent_of_failure (grpc_function_handle_t *, char *)
static int gs_notify_agent_of_cancel (grpc_function_handle_t *, char *)
static int gs_get_server_mapping (char *, grpc_function_handle_t *, gs_va_list *, void **, int, int, int)
static int gs_parse_host_port (char *, ipaddr_t *, in_port_t *)
static int gs_parse_host_info (char *, ipaddr_t *, in_port_t *, ipaddr_t *, in_port_t *, char *)
static int grpc_request_destruct (grpc_request_t *)
static int gs_free_handle_server_list (grpc_function_handle_t *)
static void grpc_function_handle_clear (grpc_function_handle_t *)
SOCKET gs_connect_to_agent ()
grpc_error_t grpc_process_config_file (char *config_file_name)
grpc_error_t grpc_initialize (char *config_file_name)
grpc_error_t grpc_finalize ()
grpc_error_t grpc_set_criteria (grpc_function_handle_t *handle, char *c)
grpc_error_t grpc_function_handle_default (grpc_function_handle_t *handle, char *func_name)
grpc_error_t grpc_function_handle_default_ns (grpc_function_handle_t *handle, char *func_name)
grpc_error_t grpc_function_handle_init (grpc_function_handle_t *handle, char *host_name, char *func_name)
grpc_error_t grpc_function_handle_destruct (grpc_function_handle_t *handle)
grpc_error_t grpc_get_handle (grpc_function_handle_t **handle, grpc_sessionid_t sessionId)
grpc_request_t * grpc_get_request (grpc_sessionid_t sessionId)
grpc_error_t grpc_call (grpc_function_handle_t *handle,...)
grpc_error_t grpc_call_async (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId,...)
grpc_error_t grpc_call_arg_list (grpc_function_handle_t *handle, gs_va_list *list)
grpc_error_t grpc_call_arg_list_async (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId, gs_va_list *list)
grpc_error_t grpc_call_arg_stack (grpc_function_handle_t *handle, grpc_arg_stack *stack)
grpc_error_t grpc_call_arg_stack_async (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId, grpc_arg_stack *stack)
static int gs_req_child_waitpid (grpc_request_t *req, int options)
grpc_error_t grpc_probe (grpc_sessionid_t sessionID)
grpc_error_t grpc_probe_or (grpc_sessionid_t *idArray, size_t length, grpc_sessionid_t *idPtr)
grpc_error_t grpc_cancel (grpc_sessionid_t sessionID)
grpc_error_t grpc_cancel_all (void)
grpc_error_t grpc_wait (grpc_sessionid_t sessionID)
grpc_error_t grpc_wait_and (grpc_sessionid_t *idArray, size_t length)
grpc_error_t grpc_wait_or (grpc_sessionid_t *idArray, size_t length, grpc_sessionid_t *idPtr)
grpc_error_t grpc_wait_all (void)
grpc_error_t grpc_wait_any (grpc_sessionid_t *idPtr)
void grpc_perror (char *str)
char * grpc_minor_error_string (grpc_error_t minor_errno)
char * grpc_error_string (grpc_error_t error_code)
grpc_error_t grpc_get_error (grpc_sessionid_t sessionID)
grpc_error_t grpc_get_failed_sessionid (grpc_sessionid_t *idPtr)
grpc_arg_stack * grpc_arg_stack_new (int max)
int grpc_arg_stack_push_arg (grpc_arg_stack *stack, void *arg)
void * grpc_arg_stack_pop_arg (grpc_arg_stack *stack)
int grpc_arg_stack_destruct (grpc_arg_stack *stack)
grpc_error_t grpc_serialize_request (grpc_sessionid_t sessionID, char **str)
grpc_error_t grpc_deserialize_request (char *str, grpc_request_t *req)
grpc_error_t grpc_retrieve (char *request_str,...)
int gs_measure_network_perf (grpc_function_handle_t *handle)
static int gs_server_compare_total_time (const void *p1, const void *p2)
int gs_sort_servers_on_comp_plus_comm (grpc_function_handle_t *handle, int data_size)
int gs_get_total_arg_size (grpc_function_handle_t *handle)
static int get_next_request_id ()
static int gs_handle_blocking_call (grpc_function_handle_t *handle, gs_va_list *argptr, void **argstack, SOCKET sock, int my_dsig)
static int gs_handle_nonblocking_call (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId, gs_va_list *argptr, void **argstack, SOCKET sock, int my_dsig, char *request_id)
grpc_error_t gs_wait_common (grpc_request_t *req)
int grpc_request_destruct_free_clear (grpc_sessionid_t sessionId)
grpc_error_t grpc_call_ft (grpc_function_handle_t *handle,...)
grpc_error_t grpc_call_valist_ft (grpc_function_handle_t *handle, gs_va_list *argptr)
grpc_error_t grpc_call_async_ft (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId,...)
grpc_error_t grpc_call_valist_async_ft (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId, gs_va_list *argptr)
grpc_error_t grpc_call_arg_stack_ft (grpc_function_handle_t *handle, grpc_arg_stack *stack)
grpc_error_t grpc_call_arg_stack_async_ft (grpc_function_handle_t *handle, grpc_sessionid_t *sessionId, grpc_arg_stack *stack)
grpc_error_t grpc_profile (grpc_profile_t *prof)
grpc_error_t grpc_set_client_major (char *maj)
grpc_error_t grpc_set_default_major (char *maj)
grpc_error_t grpc_set_client_language (int lang)
grpc_error_t grpc_probe_ft (grpc_sessionid_t sessionID)
grpc_error_t grpc_wait_ft (grpc_sessionid_t sessionID)
static grpc_error_t gs_resubmit_common (grpc_sessionid_t sessionID)
grpc_error_t * grpc_farm (char *iteration, char *func_name,...)
grpc_error_t grpc_farm_set_failure_status (int *statuses, int num_req, grpc_sessionid_t *sessionids)
grpc_error_t * grpc_farming (int start, int end, char *func_name, va_list argptr)
grpc_error_t grpc_send_farming_request (grpc_function_handle_t *handle, grpc_sessionid_t *sid, grpc_iterator_t **iterator_array, int nb_args)
grpc_error_t grpc_setup_farming_args (gs_problem_t *problem, grpc_iterator_t **it_array, int nb_args)
grpc_error_t grpc_generate_array_from_iterators (gs_problem_t *pd, grpc_void_star_or_int_t **stackarray, grpc_iterator_t **iterator_array, int nb_args)
grpc_error_t grpc_construct_iterator_array (va_list argptr, int nb_args, grpc_iterator_t ***iterator_array, int start)
void grpc_free_iterator (grpc_iterator_t *it)
void grpc_free_specific_iterator (grpc_specific_iterator_t *it)
grpc_iterator_t * grpc_int (char *s)
grpc_iterator_t * grpc_int_array (int *array, char *expression)
grpc_iterator_t * grpc_ptr_array (void **array, char *expression)
grpc_void_star_or_int_t grpc_get_next (grpc_iterator_t *it, int arg_type)
grpc_void_star_or_int_t grpc_get_value (grpc_specific_iterator_t *it, int i, int arg_type)
int grpc_eval_integer (char *s, int i)
grpc_error_t grpc_get_servers (char **info)
grpc_error_t grpc_get_problems (char **info)
int gs_smart_map_two_cycles (char *mapper_name, char *comm_type)
 Generates a mapping solution for a group of tasks.
int gs_smart_map_X (char *mapper_name)
int gs_smart_map_ft_X (char *mapper_name)
int grpc_local_X ()

Variables

static int current_pass = 0
char * GRPC_ERROR_MESSAGES []
char * GRPC_MINOR_ERROR_MESSAGES []
grpc_error_t grpc_errno = GRPC_NO_ERROR
gs_service_error_enum_t grpc_minor_errno = GRPC_NO_MINOR_ERROR
int grpc_client_major = 'r'
int grpc_client_lang = GS_CALL_FROM_C
int grpc_user_set_major = FALSE
grpc_profile_t * grpc_profile_next = NULL
char grpc_user [GRPC_USER_INFO_LEN]
char grpc_host [GRPC_USER_INFO_LEN]
char grpc_domain [GRPC_USER_INFO_LEN]
char grpc_cid_str [2 *CID_LEN+1]
int grpc_measure_comm = 1
int grpc_measure_comm_num_servers = GS_MAX_PINGS
int grpc_measure_comm_cache_ttl = GS_DEFAULT_CACHE_TTL
double grpc_measure_comm_time_thresh = GS_DEFAULT_TIME_THRESH
icl_hash_t * grpc_comm_cache = NULL
static grpc_request_t * grpc_outstanding_requests [MAX_GRPC_REQUESTS]
static grpc_profile_t * grpc_profile_info [MAX_GRPC_REQUESTS]
static grpc_error_t grpc_errors [MAX_GRPC_REQUESTS]
static grpc_sessionid_t grpc_last_failed_sid [MAX_GRPC_REQUESTS]
static int grpc_last_failed_idx = -1
static gs_service_error_enum_t grpc_minor_errors [MAX_GRPC_REQUESTS]
static int grpc_initialized = FALSE
static agent_host_info_t * agent_resolved = NULL

Detailed Description

This file contains the implementation of a GridRPC compliant remote procedure call system.

In addition to the standard API, we have developed several extensions: -retry based fault tolerance -ability to specify arguments using va_list -ability to retrieve previous jobs via serialized request id -ability to specify server selection criteria

Definition in file gsgrpc.c.


Define Documentation

#define ERROR_MAIN

Definition at line 28 of file gsgrpc.c.

#define FALSE   0

Definition at line 48 of file gsgrpc.c.

 
#define GRPC_CLEAR_ERRORS (  ) 
Value:
do { \
  memset(grpc_errors, 0, MAX_GRPC_REQUESTS * sizeof(*grpc_errors));\
  memset(grpc_minor_errors, 0, MAX_GRPC_REQUESTS * sizeof(*grpc_minor_errors));\
  } while(0);

Macros for error checking/handling

Definition at line 274 of file gsgrpc.c.

#define GRPC_FAIL_IF_NOT_INITIALIZED ( retval   ) 
Value:
if(!grpc_initialized) { \
    grpc_errno = GRPC_NOT_INITIALIZED; \
    grpc_minor_errno = GRPC_NO_MINOR_ERROR; \
    return retval; \
  }

Definition at line 279 of file gsgrpc.c.

#define GS_DEFAULT_CACHE_TTL   300

Definition at line 215 of file gsgrpc.c.

#define GS_DEFAULT_TIME_THRESH   1.0

Definition at line 216 of file gsgrpc.c.

#define GS_MAX_PINGS   5

Definition at line 214 of file gsgrpc.c.

#define GS_PORT_DELIM   '/'

GS_PORT_DELIM and GS_PROXY_DELIM specify the delimiters to be used in parsing "assigned-server" requests. The current format is: serverhost/serverportproxyhost/proxyport

Note: don't use ":" for either delimiter since it will interfere with GridSolve.

Definition at line 212 of file gsgrpc.c.

#define GS_PROXY_DELIM   '%'

Definition at line 213 of file gsgrpc.c.

#define TRUE   1

Definition at line 45 of file gsgrpc.c.

#define va_copy ( dst,
src   )     memcpy (&dst, &src, sizeof(va_list))

Definition at line 59 of file gsgrpc.c.


Function Documentation

static int get_next_request_id (  )  [static]

Get the next available request id.

Returns:
next available request id number.

Definition at line 3016 of file gsgrpc.c.

{
  int i;

  for(i = 0; i < MAX_GRPC_REQUESTS; i++) {
    if(grpc_outstanding_requests[i] == NULL)
      return i;
  }

  return -1;
}

Here is the caller graph for this function:

int grpc_arg_stack_destruct ( grpc_arg_stack *  stack  ) 

Frees a previously allocated stack.

Parameters:
stack -- the argument stack to be freed.
Returns:
-1 on failure (invalid argument), 0 otherwise.

Definition at line 2014 of file gsgrpc.c.

{
  if(!stack)
    return -1;

  if(stack->args)
    free(stack->args);

  free(stack);

  return 0;
}

Here is the caller graph for this function:

grpc_arg_stack* grpc_arg_stack_new ( int  max  ) 

Creates a new argument stack for use with the argument stack calling sequence.

Parameters:
max -- the maximum depth of the stack (i.e. the number of arguments that can be pushed on this stack).
Returns:
pointer to the new grpc_arg_stack, or NULL if there was an error.

Definition at line 1941 of file gsgrpc.c.

{
  grpc_arg_stack *tmp;

  tmp = (grpc_arg_stack *) malloc(sizeof(grpc_arg_stack));

  if(!tmp)
    return NULL;

  tmp->max_size = max;
  tmp->top = -1;
  tmp->args = (void **) calloc(max, sizeof(void *));

  if(!tmp->args) {
    free(tmp);
    return NULL;
  }

  return tmp;
}

Here is the caller graph for this function:

void* grpc_arg_stack_pop_arg ( grpc_arg_stack *  stack  ) 

Pop the top value off of the stack and return it.

Parameters:
stack -- the argument stack from which the arg should be popped.
Returns:
top stack value or NULL if the stack is empty.

Definition at line 1994 of file gsgrpc.c.

{
  if(!stack)
    return NULL;

  if(stack->top == -1)
    return NULL;

  return stack->args[stack->top--];
}

int grpc_arg_stack_push_arg ( grpc_arg_stack *  stack,
void *  arg 
)

Pushes 'arg' onto the stack.

Parameters:
stack -- the argument stack onto which the arg should be pushed.
arg -- pointer to the argument to be pushed.
Returns:
0 on success, -1 on failure

Definition at line 1972 of file gsgrpc.c.

{
  if(!stack)
    return -1;

  if(stack->top == (stack->max_size - 1))
    return -1;

  stack->args[++stack->top] = arg;

  return 0;
}

Here is the caller graph for this function:

grpc_error_t grpc_call ( grpc_function_handle_t *  handle,
  ... 
)

Perform a blocking GridRPC call.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
... -- the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1001 of file gsgrpc.c.

{

#ifdef GS_SMART_GRIDSOLVE

  if(smart_phase==GS_SMART_EXEC_TASK_FAIL){
    return GRPC_NO_ERROR;
  }
#endif

  gs_va_list argptr;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  va_start(argptr.args, handle);

  return gs_call_common(handle, NULL, &argptr, NULL, TRUE);
}

Here is the call graph for this function:

grpc_error_t grpc_call_arg_list ( grpc_function_handle_t *  handle,
gs_va_list *  list 
)

Definition at line 1070 of file gsgrpc.c.

                                                                     {
        return gs_call_common(handle, NULL, list, NULL, TRUE);
}

Here is the call graph for this function:

grpc_error_t grpc_call_arg_list_async ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
gs_va_list *  list 
)

Definition at line 1074 of file gsgrpc.c.

                                                           {
        return gs_call_common(handle, sessionId, list, NULL, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_arg_stack ( grpc_function_handle_t *  handle,
grpc_arg_stack *  stack 
)

Perform a blocking GridRPC call using the argument stack calling sequence.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
stack -- the argument stack containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1104 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!stack || !stack->args)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_ARGSTACK);
  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  return gs_call_common(handle, NULL, NULL, stack->args, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_arg_stack_async ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
grpc_arg_stack *  stack 
)

Perform a non-blocking GridRPC call using the argument stack calling sequence.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
stack -- the argument stack containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1143 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!stack || !stack->args) 
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_ARGSTACK);
  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  return gs_call_common(handle, sessionId, NULL, stack->args, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_arg_stack_async_ft ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
grpc_arg_stack *  stack 
)

Perform a non-blocking GridRPC call. This is the same as grpc_call_async_ft(), except that it takes an argument stack of the arguments.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
stack -- argument stack containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4532 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!stack || !stack->args)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_ARGSTACK);
  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  return gs_call_common_ft(handle, sessionId, NULL, stack->args, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_arg_stack_ft ( grpc_function_handle_t *  handle,
grpc_arg_stack *  stack 
)

Perform a blocking GridRPC call. This is the same as grpc_call_ft(), except that it takes an argument stack of the arguments.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
stack -- argument stack containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4492 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!stack || !stack->args)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_ARGSTACK);
  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  return gs_call_common_ft(handle, NULL, NULL, stack->args, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_async ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
  ... 
)

Perform a non-blocking GridRPC call.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
... -- the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1044 of file gsgrpc.c.

{

#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase==GS_SMART_EXEC_TASK_FAIL){
    return GRPC_NO_ERROR;
  }

#endif


  gs_va_list argptr;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  va_start(argptr.args, sessionId);

  return gs_call_common(handle, sessionId, &argptr, NULL, FALSE);
}

Here is the call graph for this function:

grpc_error_t grpc_call_async_ft ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
  ... 
)

Perform a non-blocking GridRPC call. This is the fault tolerant version of grpc_call_async. If there is a failure executing the function, the problem will be resubmitted to another server transparently to the user.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
... -- the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4422 of file gsgrpc.c.

{
  gs_va_list argptr;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  va_start(argptr.args, sessionId);

  return gs_call_common_ft(handle, sessionId, &argptr, NULL, FALSE);
}

Here is the call graph for this function:

grpc_error_t grpc_call_ft ( grpc_function_handle_t *  handle,
  ... 
)

Perform a blocking GridRPC call. This is the fault tolerant version of grpc_call. If there is a failure executing the function, the problem will be resubmitted to another server transparently to the user.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
... -- the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4353 of file gsgrpc.c.

{
  gs_va_list argptr;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  va_start(argptr.args, handle);

  return gs_call_common_ft(handle, NULL, &argptr, NULL, TRUE);
}

Here is the call graph for this function:

grpc_error_t grpc_call_valist_async_ft ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
gs_va_list *  argptr 
)

Perform a non-blocking GridRPC call. This is the same as grpc_call_async_ft(), except that it takes a va_list of the arguments.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
argptr -- va_list containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4460 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  return gs_call_common_ft(handle, sessionId, argptr, NULL, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_call_valist_ft ( grpc_function_handle_t *  handle,
gs_va_list *  argptr 
)

Perform a blocking GridRPC call. This is the same as grpc_call_ft(), except that it takes a va_list of the arguments.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
argptr -- va_list containing the arguments to be passed to the remote procedure.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4388 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  return gs_call_common_ft(handle, NULL, argptr, NULL, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_cancel ( grpc_sessionid_t  sessionID  ) 

Cancel a previously submitted non-blocking request.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR if the specified request was cancelled successfully. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1391 of file gsgrpc.c.

{
  grpc_function_handle_t *handle;
  gs_server_t *srv;
  SOCKET sock;
  int tag;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionID])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(gs_notify_agent_of_cancel(grpc_outstanding_requests[sessionID]->handle, 
       grpc_outstanding_requests[sessionID]->request_id) < 0)
    ERRPRINTF("Warning: failed to notify agent of job cancellation.\n");

  if(grpc_outstanding_requests[sessionID]->s_pid > 0) {
    if(gs_req_child_waitpid(grpc_outstanding_requests[sessionID], GS_WNOHANG) == 0) {
      /*
       * the child is still sending data to the parent.  kill it. 
       */

      kill(grpc_outstanding_requests[sessionID]->s_pid, GS_SIGKILL);
    }
  }

  handle = grpc_outstanding_requests[sessionID]->handle;

  if(!handle)
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  srv = handle->server_list[handle->srv_idx];

  sock = gs_connect_to_host(srv->componentid, srv->ipaddress, srv->port,
                            srv->proxyip, srv->proxyport);

  if(sock == INVALID_SOCKET)
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_SERVER_CONNECTION);

  if((gs_send_tag(sock, GS_PROT_KILL_JOB) < 0) ||
     (gs_send_string(sock, VERSION) < 0)) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  }
            
  if(gs_recv_tag(sock, &tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  } 
    
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;

    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
  } 

  if(gs_send_string(sock, grpc_outstanding_requests[sessionID]->request_id) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  }

  if(gs_recv_tag(sock, &tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  }

  proxy_close(sock);

  switch (tag) {
    case GS_PROT_OK:
      grpc_request_destruct(grpc_outstanding_requests[sessionID]);
      free(grpc_outstanding_requests[sessionID]);
      grpc_outstanding_requests[sessionID] = NULL;
      grpc_profile_info[sessionID] = NULL;
      GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
    default:
      ERRPRINTF("cancel failed: %s\n", gs_service_error[tag]);
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, tag);
  }

  /*
   * shouldn't reach here 
   */
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_cancel_all ( void   ) 

Cancel all previously submitted non-blocking requests.

Returns:
GRPC_NO_ERROR if all requests were cancelled successfully. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1494 of file gsgrpc.c.

{
  grpc_error_t last_minor_error = GRPC_NO_MINOR_ERROR;
  int i, saw_failure = FALSE;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  for(i = 0; i < MAX_GRPC_REQUESTS; i++)
    if(grpc_outstanding_requests[i] != NULL)
      if(grpc_cancel(i) != GRPC_NO_ERROR) {
        saw_failure = TRUE;
        last_minor_error = grpc_minor_errno;
      }

  if(saw_failure)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, last_minor_error);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

grpc_error_t grpc_construct_iterator_array ( va_list  argptr,
int  nb_args,
grpc_iterator_t ***  iterator_array,
int  start 
)

constructs Iterator array from the arguments(iterators) to the farming call

Parameters:
argptr -- ptr to the arguments to the farming call
nb_args -- number of arguments in the farming call
iterator_array -- Array of iterator to be created from each argument
start -- starting index of the argptr
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5493 of file gsgrpc.c.

{
  grpc_iterator_t **new;
  int i;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  new = (grpc_iterator_t **) calloc(nb_args, sizeof(grpc_iterator_t *));

  for(i = 0; i < nb_args; i++) {
    new[i] = (grpc_iterator_t *) va_arg(argptr, void *);
    new[i]->i = start;
  }
  *iterator_array = new;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the caller graph for this function:

grpc_error_t grpc_deserialize_request ( char *  str,
grpc_request_t *  req 
)

Deserialize a saved request from string to grpc_request_t structure. This allows the user to take a request that was previously serialized (not necessarily on this machine) and retrieve the results from the remote server.

Parameters:
str -- the serialized request.
req -- on return, this structure contains the relevant information needed to retrieve the results.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 2109 of file gsgrpc.c.

{
  char *p, *endp, *tmp_str;
  int i, len;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  tmp_str = strdup(str);
  if(!tmp_str)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  p = tmp_str;
  len = strlen(tmp_str);

  for(i = 0; (tmp_str[i] != '\n') && (i < len); i++)
    /*
     * spin 
     */ ;

  if(i == len) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_SERIALIZED_REQ);
  }

  tmp_str[i] = '\0';

  req->request_id = CALLOC(strlen(p), sizeof(char));
  if(!req->request_id) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  sscanf(p, "<request id=\"%[^\"]\">", req->request_id);

  req->handle = (grpc_function_handle_t *) CALLOC(1, 
     sizeof(grpc_function_handle_t));
  if(!req->handle) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  p = tmp_str + i + 1;
  p = strstr(p, "<handle");

  for(; (tmp_str[i] != '\n') && (i < len); i++)
    /*
     * spin 
     */ ;

  if(i == len) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_SERIALIZED_REQ);
  }

  tmp_str[i] = '\0';

  req->handle->func_name = CALLOC(strlen(p), sizeof(char));
  if(!req->handle->func_name) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  sscanf(p, "<handle func_name=\"%[^\"]\">", req->handle->func_name);

  p = tmp_str + i + 1;

  endp = strstr(p, "<problem name");
  if(!endp) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_SERIALIZED_REQ);
  }

  *(endp - 1) = '\0';

  req->handle->srv_idx = 0;
  req->handle->num_servers = 1;
  req->handle->server_list =
      (gs_server_t **) CALLOC(1, sizeof(gs_server_t *));
  if(!req->handle->server_list) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  req->handle->server_list[req->handle->srv_idx] =
      (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
  if(!req->handle->server_list[req->handle->srv_idx]) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }
  req->s_pid = -1;

  if(gs_decode_server(p, req->handle->server_list[req->handle->srv_idx]) < 0) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SERVER_DECODE);
  }

  p = endp;

  endp = strstr(p, "</problem>");
  if(!endp) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_SERIALIZED_REQ);
  }

  endp += strlen("</problem>");
  *endp = '\0';

  req->problem = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
  if(!req->problem) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  if(gs_decode_problem(p, req->problem) < 0) {
    free(tmp_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_PROBLEM_DECODE);
  }

  free(tmp_str);

  req->handle->problem_desc = (gs_problem_t *) malloc(sizeof(gs_problem_t));

  if(!req->handle->problem_desc)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  if(gs_dup_problem(req->handle->problem_desc, req->problem) < 0)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_DUP_PROBLEM_FAILED);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* grpc_error_string ( grpc_error_t  error_code  ) 

Given a GridRPC error code (typically the global grpc_errno), return a string explaining the error.

Parameters:
error_code -- the GridRPC error code to look up.
Returns:
string representing the given error code.

Definition at line 1876 of file gsgrpc.c.

{
  if((error_code < 0) || (error_code >= GRPC_LAST_ERROR_CODE))
    return "Invalid Error Code";

  return GRPC_ERROR_MESSAGES[error_code];
}

Here is the caller graph for this function:

int grpc_eval_integer ( char *  s,
int  i 
)

Evaluates the expression for i = i

Parameters:
s -- Character string specifying the iteration
i -- Specifies the iteration index i's value
Returns:
don't know why its returning i

Definition at line 5758 of file gsgrpc.c.

{
  return i;
}

Here is the caller graph for this function:

grpc_error_t* grpc_farm ( char *  iteration,
char *  func_name,
  ... 
)

Task farming interface. This submits multiple instances of the same problem with different parameters.

Parameters:
iteration -- a string of the form "i=1,200" expressing the number of iterations of the farming to perform
func_name -- the function to be called
... -- the rest of the arguments to the problem
Returns:
an array of grpc_error_t. On success, the first element of this array is GRPC_NO_ERROR. On catastrophic failure, this may return NULL. On other failures, the first element is GRPC_OTHER_ERROR_CODE and the remaining N elements represent the return value of each of the N calls in the farmed request.

Definition at line 5038 of file gsgrpc.c.

{
  int start, end, *returned_value;
  va_list argptr;
  char *buf;

  GRPC_FAIL_IF_NOT_INITIALIZED(NULL);

  if((!iteration) || (!func_name)) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return NULL;
  }

  buf = strdup(iteration);

  if(!buf) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return NULL;
  }

  /* get the <start> end the <end> */
  if (sscanf(buf,"i=%d,%d",&start,&end) != 2)
  {
    free(buf);
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    returned_value = (int *)calloc(1,sizeof(int));
    returned_value[0] = GRPC_OTHER_ERROR_CODE;
    return returned_value;
  }

  free(buf);

  va_start(argptr, func_name);

  return grpc_farming(start, end, func_name, argptr);
}

Here is the call graph for this function:

grpc_error_t grpc_farm_set_failure_status ( int *  statuses,
int  num_req,
grpc_sessionid_t *  sessionids 
)

Sets the error status for the previously submitted farming request.

Parameters:
statuses -- status array
num_req -- number of requests submitted
sessionids -- array of session IDs
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_OTHER_ERROR_CODE: match not found for session id

Definition at line 5088 of file gsgrpc.c.

{
  grpc_sessionid_t failed_sid;
  int i;

  if(grpc_get_failed_sessionid(&failed_sid) == GRPC_NO_ERROR) {
    for(i = 0; i < num_req; i++) {
      if(sessionids[i] == failed_sid) {
        statuses[i] = grpc_get_error(failed_sid);
        GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
      }
    }
  }

  /* if we reach here, the session id was not found */
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_FARM_SESSIONID_NOT_FOUND);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t* grpc_farming ( int  start,
int  end,
char *  func_name,
va_list  argptr 
)

Low-level task farming stuff. Users should not call this; they should instead call grpc_farm().

Parameters:
start -- initial value of the loop variable
end -- final value of the loop variable
func_name -- the function to call
argptr -- va_list of the arguments to the problem
Returns:
an array of grpc_error_t. On success, the first element of this array is GRPC_NO_ERROR. On catastrophic failure, this may return NULL. On other failures, the first element is GRPC_OTHER_ERROR_CODE and the remaining N elements represent the return value of each of the N calls in the farmed request.

Definition at line 5124 of file gsgrpc.c.

{
  int *statuses;
  int nb_requests;
  int window_size;          /* window size = 2 * # of capable servers */
  int status;
  int i, j;
  int nb_args;
  int pending;
  gs_argument_t *argp = NULL;
  grpc_iterator_t **iterator_array = NULL;
  grpc_error_t *returned_value;
  grpc_sessionid_t *sessionids;
  grpc_function_handle_t *handles;

  GRPC_FAIL_IF_NOT_INITIALIZED(NULL);

  if(!func_name) {
    grpc_errno = GRPC_NOT_INITIALIZED;
    grpc_minor_errno = GRPC_NULL_FUNCTION_NAME;
    return NULL;
  }

  /*
   * Start the farming 
   */
  nb_requests = end - start + 1;
  statuses = (int *) calloc(nb_requests, sizeof(int));
  sessionids = (grpc_sessionid_t *) calloc(nb_requests,
     sizeof(grpc_sessionid_t));
  handles = (grpc_function_handle_t *) calloc(nb_requests,
     sizeof(grpc_function_handle_t));

  if(!statuses || !sessionids || !handles) {
    if(statuses) free(statuses);
    if(sessionids) free(sessionids);
    if(handles) free(handles);
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    grpc_minor_errno = GRPC_NO_MINOR_ERROR;
    return NULL;
  }

  if(grpc_function_handle_default(&handles[0], func_name) != GRPC_NO_ERROR) {
    ERRPRINTF("Could not get function handle\n");
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    grpc_minor_errno = GRPC_NO_MINOR_ERROR;
    return NULL;
  }

  /*
   * Getting the nb_args 
   */
  nb_args = 0;
  for(argp = handles[0].problem_desc->arglist; argp != NULL; argp = argp->next)
    nb_args++;

  window_size = handles[0].num_servers * 2;

  grpc_function_handle_destruct(&handles[0]);

  if(grpc_construct_iterator_array(argptr, nb_args, &iterator_array, start) == -1)
    ERRPRINTF("Could not construct iterator array\n");

  /*
   * Filling problem_desc->arglist->data 
   */

  DBGPRINTF("# of requests is %d \n", nb_requests);

  if(nb_requests <= window_size) {
    j = nb_requests;
    pending = 0;
  }
  else {
    j = window_size;
    pending = 1;
  }

  for(i = 0; i < j; i++)
  {
    
    if(grpc_function_handle_default(&handles[i], func_name) != 
        GRPC_NO_ERROR)
    {
      statuses[i] = grpc_errno;
      sessionids[i] = -1;
    }
    else 
      statuses[i] = grpc_send_farming_request(&handles[i], &sessionids[i], 
        iterator_array, nb_args);
  }

  if(!pending) {
    if(grpc_wait_and(sessionids, nb_requests) != GRPC_NO_ERROR)
      grpc_farm_set_failure_status(statuses, nb_requests, sessionids);
  }
  else {                        
    int num_retrieved = 0;

    while(num_retrieved < nb_requests) {
      if(grpc_wait_any(&status) != GRPC_NO_ERROR)
        grpc_farm_set_failure_status(statuses, nb_requests, sessionids);
      
      num_retrieved++;

      if(i < nb_requests) {
        if(grpc_function_handle_default(&handles[i], func_name) != 
            GRPC_NO_ERROR)
        {
          statuses[i] = grpc_errno;
          sessionids[i] = -1;
        }
        else
          statuses[i] =
            grpc_send_farming_request(&handles[i], &sessionids[i], 
               iterator_array, nb_args);
        i++;
      }
    }
  }

  status = 1;
  for(i = 0; i < nb_requests; i++) {
    if(statuses[i] != GRPC_NO_ERROR)
      status = -1;

    grpc_function_handle_destruct(&handles[i]);
  }
  free(handles);

  if(status == -1) {
    returned_value = (grpc_error_t *) calloc(nb_requests + 1, sizeof(grpc_error_t));
    returned_value[0] = GRPC_OTHER_ERROR_CODE;
    for(i = 0; i < nb_requests; i++)
      returned_value[i + 1] = statuses[i];
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    grpc_minor_errno = GRPC_NO_MINOR_ERROR;
  }
  else {
    returned_value = (grpc_error_t *) calloc(1, sizeof(grpc_error_t));
    returned_value[0] = GRPC_NO_ERROR;
    grpc_errno = GRPC_NO_ERROR;
    grpc_minor_errno = GRPC_NO_MINOR_ERROR;
  }

  return returned_value;
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_finalize (  ) 

Release any resources being used by GridRPC.

Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 526 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  cleanup_sockets();

  grpc_initialized = FALSE;

  if(grpc_comm_cache)
    icl_hash_destroy(grpc_comm_cache, free, free);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void grpc_free_iterator ( grpc_iterator_t *  it  ) 

Frees the Iterator memory

Parameters:
it -- Iterator to be freed

Definition at line 5519 of file gsgrpc.c.

{
  if(!it) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return;
  }

  grpc_free_specific_iterator(it->specific);
  free(it);
}

Here is the call graph for this function:

void grpc_free_specific_iterator ( grpc_specific_iterator_t *  it  ) 

Frees the Specific Iterator memory

Parameters:
it -- Specific Iterator to be freed

Definition at line 5537 of file gsgrpc.c.

{
  if(!it) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return;
  }

  switch (it->type) {
    case INT_ITERATOR:
      free(it->it.int_iterator->expression);
      free(it->it.int_iterator);
      break;
    case INT_ARRAY_ITERATOR:
      free(it->it.int_array_iterator->expression);
      free(it->it.int_array_iterator);
      break;
    case PTR_ARRAY_ITERATOR:
      free(it->it.ptr_array_iterator->expression);
      free(it->it.ptr_array_iterator);
      break;
  }

  free(it);
}

Here is the caller graph for this function:

static void grpc_function_handle_clear ( grpc_function_handle_t *  handle  )  [static]

Clear the function handle structure by setting NULLs and error values.

Parameters:
handle -- The function handle which is to be cleared
Returns:
nothing

Definition at line 597 of file gsgrpc.c.

{
  if(!handle)
    return;

  handle->func_name = NULL;
  handle->num_servers = 0;
  handle->srv_idx = 0;
  handle->server_list = NULL;
  handle->problem_desc = NULL;
  handle->criteria = NULL;
  handle->bind_servers_at_call_time = 0;
  handle->agent_taskid = -1;
  handle->num_calls = 0;
}

Here is the caller graph for this function:

static grpc_error_t grpc_function_handle_common ( grpc_function_handle_t *  handle,
char *  host_name,
char *  func_name 
)

This is a common function called by all the grpc_function_handle_init*() functions to initialize the function handle with the given parameters.

Parameters:
handle -- A pointer to a function handle structure (allocated by the user). On return, this structure will contain the relevant information needed for GridRPC to make remote procedure calls.
host_name -- The name of the server to be called when the handle is used to make a remote procedure call.
func_name -- The name of the function that the returned function handle will represent.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 787 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);

  if(!func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  if(host_name) {
    int i, parse_host = 0;
    gs_server_t *srv;

    handle->srv_idx = 0;
    handle->num_servers = 1;
    handle->server_list = (gs_server_t **) malloc(sizeof(gs_server_t *));

    if(!handle->server_list)
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

    handle->server_list[handle->srv_idx] =
        (gs_server_t *) CALLOC(1, sizeof(gs_server_t));

    if(!handle->server_list[handle->srv_idx])
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

    for(i = 0; i < (int)strlen(host_name); i++) {
      if(host_name[i] == GS_PORT_DELIM || host_name[i] == GS_PROXY_DELIM) {
        parse_host = 1;
        break;
      }
    }

    srv = handle->server_list[handle->srv_idx];
    srv->arch = strdup("unknown");
    srv->problemlist = NULL;
    srv->agenthost = NULL;
    srv->sa_list = NULL;

    if(parse_host) {
      if(gs_parse_host_info(host_name, &srv->ipaddress, &srv->port,
                            &srv->proxyip, &srv->proxyport,
                            srv->componentid) < 0) {
        ERRPRINTF("Error parsing info\n");
        GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_PARSE_HOST_INFO);
      }
      srv->hostname = strdup("unspecified");
    }
    else {
      srv->hostname = strdup(host_name);
      srv->port =
          getenv_int("GRIDSOLVE_SERVER_PORT",
                     GRIDSOLVE_SERVER_PORT_DEFAULT);

      if(!handle->bind_servers_at_call_time) {
        struct hostent *hp;

        if((hp = gethostbyname(host_name)) == NULL) {
          ERRPRINTF("Can't resolve host name '%s'\n", host_name);
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_RESOLV_FAILED);
        }

        memcpy((void *) &(srv->ipaddress), hp->h_addr_list[0], 
          sizeof(srv->ipaddress));

        /* since there was only hostname specified, componentID is
         * unavailable.  So initialize it with the 'wildcard' value.
         */

        memset(srv->componentid, 0xFF, CID_LEN);
      }
    }

    handle->func_name = strdup(func_name);
    handle->problem_desc = NULL;
  }
  else {
    /*
     * Use NULLS as the arg and argptr and -1 as the dsig to indicate that
     * the input args are NOT to be transferred at this time. They are not
     * known/bound yet in the standard GridRPC protocol, so they could not be 
     * transferred yet. 
     */
    if(gs_get_server_mapping(func_name, handle, NULL, NULL, -1,
          grpc_client_lang, grpc_client_major) < 0) {
      if(grpc_errno == GRPC_SERVER_NOT_FOUND ||
         grpc_errno == GRPC_NOT_INITIALIZED ||
         grpc_errno == GRPC_FUNCTION_NOT_FOUND)
        GRPC_RETURN(grpc_errno, grpc_minor_errno);
 
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
    }

    GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_function_handle_default ( grpc_function_handle_t *  handle,
char *  func_name 
)

Initializes the function handle with the given function name and does not specify the host (allows a resource broker to choose the best host.

Parameters:
handle -- A pointer to a function handle structure (allocated by the user). On return, this structure will contain the relevant information needed for GridRPC to make remote procedure calls.
func_name -- The name of the function that the returned function handle will represent.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 634 of file gsgrpc.c.

{
  grpc_function_handle_clear(handle);
  if(handle)
    handle->bind_servers_at_call_time = 0;
  return grpc_function_handle_common(handle, NULL, func_name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_function_handle_default_ns ( grpc_function_handle_t *  handle,
char *  func_name 
)

Initializes the function handle with the given function name and does not specify the host (allows a resource broker to choose the best host. This is the "GridSolve" version of "grpc_function_handle_default" which allows us to delay the actual binding of servers until the call is made, thus allowing the agent to do better scheduling.

Parameters:
handle -- A pointer to a function handle structure (allocated by the user). On return, this structure will contain the relevant information needed for GridRPC to make remote procedure calls.
func_name -- The name of the function that the returned function handle will represent.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 665 of file gsgrpc.c.

{
  grpc_function_handle_clear(handle);
  /*
   * Use any non-blank hostname and set handle->bind_servers_at_call_time to
   * 1 
   */
  if(handle)
    handle->bind_servers_at_call_time = 1;
  return grpc_function_handle_common(handle, "bind_servers_at_call_time",
                                     func_name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_function_handle_destruct ( grpc_function_handle_t *  handle  ) 

Frees the memory allocated by grpc_function_handle_init() or grpc_function_handle_default(). Note: this doesn't try to free the memory allocated for the handle structure itself since that would have been allocated by the user.

Parameters:
handle -- the function handle to be destroyed.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 905 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!handle)
    GRPC_RETURN(GRPC_INVALID_FUNCTION_HANDLE, GRPC_NULL_FUNCTION_HANDLE);

  if(handle->func_name)
    free(handle->func_name);
  gs_free_problem(handle->problem_desc);
  gs_free_handle_server_list(handle);

  if(handle->criteria) {
    free(handle->criteria);
    handle->criteria = NULL;
  }

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_function_handle_init ( grpc_function_handle_t *  handle,
char *  host_name,
char *  func_name 
)

Initializes the function handle with the given function name and host/port.

Parameters:
handle -- A pointer to a function handle structure (allocated by the user). On return, this structure will contain the relevant information needed for GridRPC to make remote procedure calls.
host_name -- The name of the server to be called when the handle is used to make a remote procedure call.
func_name -- The name of the function that the returned function handle will represent.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 701 of file gsgrpc.c.

{

#ifdef GS_SMART_GRIDSOLVE

  /*
   * if the task graph is being built then we do not want to bind the servers at call time
   */
  if(smart_phase==GS_SMART_TASK_DISCOVERY){
    return grpc_function_handle_default(handle, func_name);
  }

   
  /*
   * if we are in executing mode then we don't need to set up handles, just return with no errors
   */
  if(smart_phase==GS_SMART_EXEC_CALLED_HANDLES) {
    return grpc_function_handle_default(handle, func_name);
      GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }

  /*
   * else if we are not building or executing (i.e. we are executing in the standard gridsolve approach)
   * then just set up the handle_init as normal
   */
  else if(smart_phase==GS_SMART_STANDARD_EXEC)
  {   
    grpc_function_handle_clear(handle);
    if((handle) && strcmp(host_name, "bind_servers_at_call_time") == 0)
      handle->bind_servers_at_call_time = 1;
    else if(handle)
      handle->bind_servers_at_call_time = 0;
    return grpc_function_handle_common(handle, host_name, func_name);
  }
  
  /*
   * if none of the above set up handle_init as normal
   * 
   */
  else
  {   
    grpc_function_handle_clear(handle);
    if((handle) && strcmp(host_name, "bind_servers_at_call_time") == 0)
      handle->bind_servers_at_call_time = 1;
    else if(handle)
      handle->bind_servers_at_call_time = 0;
    return grpc_function_handle_common(handle, host_name, func_name);
  }



#else


  grpc_function_handle_clear(handle);
  if((handle) && strcmp(host_name, "bind_servers_at_call_time") == 0)
    handle->bind_servers_at_call_time = 1;
  else if(handle)
    handle->bind_servers_at_call_time = 0;
  return grpc_function_handle_common(handle, host_name, func_name);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_generate_array_from_iterators ( gs_problem_t *  pd,
grpc_void_star_or_int_t **  stackarray,
grpc_iterator_t **  iterator_array,
int  nb_args 
)
Parameters:
pd -- problem structure containing problem information
stackarray -- stack array to be generated from Iterator
iterator_array -- Array of iterators for each arguments
nb_args -- Number of arguements in farming call
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5439 of file gsgrpc.c.

{
  grpc_void_star_or_int_t *new;
  int i;
  grpc_iterator_t *it;
  int arg_type;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!pd || !iterator_array)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);

  new =
      (grpc_void_star_or_int_t *) calloc(nb_args,
                                         sizeof(grpc_void_star_or_int_t));
  for(i = 0; i < nb_args; i++) {
    it = iterator_array[i];
    arg_type = it->returned_type;
    switch (arg_type) {
      case IGNORE:
        new[i].ptr = NULL;
        break;
      case POINTER:
        new[i].ptr = grpc_get_next(it, arg_type).ptr;
        break;
      case INTEGER:
        new[i].i = grpc_get_next(it, arg_type).i;
        break;
    }
  }

  *stackarray = new;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_get_error ( grpc_sessionid_t  sessionID  ) 

Gets the error return code associated with 'sessionID'.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
the error code associated with the given session ID.

Definition at line 1894 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionID])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  return grpc_errors[sessionID];
}

Here is the caller graph for this function:

grpc_error_t grpc_get_failed_sessionid ( grpc_sessionid_t *  idPtr  ) 

Gets the most recent error return code.

Returns:
the error code most recently generated.

Definition at line 1914 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(grpc_last_failed_idx < 0) {
    *idPtr = GRPC_SESSIONID_VOID;
    return GRPC_NO_ERROR;
  }

  *idPtr = grpc_last_failed_sid[grpc_last_failed_idx];

  grpc_last_failed_idx--;

  return GRPC_NO_ERROR;
}

Here is the caller graph for this function:

grpc_error_t grpc_get_handle ( grpc_function_handle_t **  handle,
grpc_sessionid_t  sessionId 
)

Get the function handle associated with the specified non-blocking request.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 940 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionId < 0) || (sessionId >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionId])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  *handle = grpc_outstanding_requests[sessionId]->handle;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the caller graph for this function:

grpc_void_star_or_int_t grpc_get_next ( grpc_iterator_t *  it,
int  arg_type 
)

Get next Iterator element

Parameters:
it - Iterator
arg_type -- Specifies the arguemt type of the element
Returns:
Element of type grpc_void_or_int_t

Definition at line 5671 of file gsgrpc.c.

{
  grpc_void_star_or_int_t stuff;
  stuff.ptr = NULL;

  if(!it) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return stuff;
  }

  stuff = grpc_get_value(it->specific, it->i, arg_type);
  (it->i)++;

  return stuff;
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_get_problems ( char **  info  ) 

Return information about the GridSolve system in a string (the agent and names of available services)

Returns:
GRPC_NO_ERROR if success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5973 of file gsgrpc.c.

{
  char *msg=NULL;
  int i, tag;
  SOCKET sock;
  char *str1 = NULL;
  char *str2 = NULL;
  int num_problems;
  gs_problem_t ** problem_list;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sock = gs_connect_to_agent()) == INVALID_SOCKET)
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_AGENT_NOT_SET);

  if((gs_send_tag(sock, GS_PROT_PROBLEM_LIST) < 0) ||
     (gs_send_string(sock, VERSION) < 0) || 
     (gs_recv_tag(sock, &tag) < 0))
    goto error_communication_failed;
  if(tag != GS_PROT_OK) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    if(tag == GS_PROT_VERSION_MISMATCH) {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_VERSION_MISMATCH);
    } else {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }
  }

  if(gs_recv_int(sock, &num_problems) < 0) {
    goto error_communication_failed;
  }

  str1 = dstring_sprintf("AGENT: %s [%d problems]\n", agent_resolved->hostname,
    num_problems);

  if(num_problems <= 0) {
    *info = str1;
    GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }

  problem_list = (gs_problem_t **) CALLOC(num_problems, sizeof(gs_problem_t *));
  if(!problem_list) { 
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  for(i=0;i<num_problems;i++) {
    problem_list[i] = (gs_problem_t *) CALLOC(1,sizeof(gs_problem_t));
    if(gs_recv_string(sock, &msg) < 0) {
      goto error_communication_failed;
    }
    if(gs_decode_problem(msg, problem_list[i]) < 0) {
      FREE(msg);
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SERVER_DECODE);
    }
    FREE(msg);
  }

  for(i=0;i<num_problems;i++) {
    str2 = dstring_sprintf("%s\n", problem_list[i]->name);
    str1 = dstring_append_free(str1, str2);
  }
  
  for(i=0;i<num_problems;i++) 
    FREE(problem_list[i]);
  FREE(problem_list);

  if(sock != INVALID_SOCKET) proxy_close(sock);
  
  *info = str1;
  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  
  
 error_communication_failed:
  DBGPRINTF("Client Error: Communication failed\n");
  FREE(msg);
  if(sock != INVALID_SOCKET)  proxy_close(sock);
  GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_request_t* grpc_get_request ( grpc_sessionid_t  sessionId  ) 

Get the request structure associated with the specified non-blocking request.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
pointer to the request or NULL if not found.

Definition at line 966 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(NULL);

  if((sessionId < 0) || (sessionId >= MAX_GRPC_REQUESTS))
    return NULL;

  if(!grpc_outstanding_requests[sessionId])
    return NULL;

  return grpc_outstanding_requests[sessionId];
}

Here is the caller graph for this function:

grpc_error_t grpc_get_servers ( char **  info  ) 

Return information about the GridSolve system in a string (the agent and servers)

Returns:
GRPC_NO_ERROR if success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5875 of file gsgrpc.c.

{
  char dottedIP[20], proxy_dottedIP[20];
  char *msg=NULL;
  int i, num_servers, tag;
  gs_server_t **server_list;
  SOCKET sock;
  char *str1 = NULL;
  char *str2 = NULL;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sock = gs_connect_to_agent()) == INVALID_SOCKET)
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_AGENT_NOT_SET);

  if((gs_send_tag(sock, GS_PROT_SERVER_LIST) < 0) ||
     (gs_send_string(sock, VERSION) < 0) || 
     (gs_recv_tag(sock, &tag) < 0))
    goto error_communication_failed;
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH) {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_VERSION_MISMATCH);
    } else {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }
  }

  if(gs_recv_int(sock, &num_servers) < 0)
    goto error_communication_failed;
  
  str1 = dstring_sprintf("AGENT: %s [%d servers]\n", agent_resolved->hostname,
     num_servers);
  
  if(num_servers <= 0) {
    *info = str1;
    GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }

  server_list = (gs_server_t **) CALLOC(num_servers, sizeof(gs_server_t *));
  if(!server_list) 
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  for(i=0;i<num_servers;i++) {
    server_list[i] = (gs_server_t *) CALLOC(1,sizeof(gs_server_t));
    if(gs_recv_string(sock, &msg) < 0) {
      goto error_communication_failed;
    }
    if(gs_decode_server(msg, server_list[i]) < 0) {
      FREE(msg);
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SERVER_DECODE);
    }
    FREE(msg)
  }

  for(i=0;i<num_servers;i++) {
    proxy_ip_to_str(server_list[i]->ipaddress, dottedIP);
    proxy_ip_to_str(server_list[i]->proxyip, proxy_dottedIP);
    if(server_list[i]->proxyip != 0)
      str2 = dstring_sprintf("SERVER: %s (%s:%d, proxy=%s:%d)\n", server_list[i]->hostname, 
                 dottedIP, server_list[i]->port, proxy_dottedIP, 
                 server_list[i]->proxyport);
    else
      str2 = dstring_sprintf("SERVER: %s (%s:%d)\n", server_list[i]->hostname, 
                 dottedIP, server_list[i]->port);
    str1 = dstring_append_free(str1, str2);
  }

  for(i=0;i<num_servers;i++) 
    FREE(server_list[i]);
  FREE(server_list);

  if(sock != INVALID_SOCKET)  proxy_close(sock);

  *info = str1;
  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  
  
 error_communication_failed:
  DBGPRINTF("Client Error: Communication failed\n");
  FREE(msg);
  if(sock != INVALID_SOCKET)  proxy_close(sock);
  GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_void_star_or_int_t grpc_get_value ( grpc_specific_iterator_t *  it,
int  i,
int  arg_type 
)

Get next Iterator element value

Parameters:
it - Iterator
i -- Specifies the index of the element
arg_type -- Specifies the arguemt type of the element
Returns:
Element of type grpc_void_or_int_t

Definition at line 5698 of file gsgrpc.c.

{
  grpc_void_star_or_int_t stuff;
  int *x;
  stuff.ptr = NULL;

  if(!it) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return stuff;
  }

  switch (it->type) {
    case INT_ITERATOR:
      stuff.i = grpc_eval_integer(it->it.int_iterator->expression, i);
      break;
    case INT_ARRAY_ITERATOR:
      if(arg_type == INTEGER) {
        stuff.i =
            (it->it.int_array_iterator->
             array)[grpc_eval_integer(it->it.int_array_iterator->expression,
                                      i)];
      }
      else if(arg_type == POINTER) {
        stuff.ptr = (it->it.int_array_iterator->array) +
            grpc_eval_integer(it->it.int_array_iterator->expression, i);
      }
      break;
    case PTR_ARRAY_ITERATOR:
      if(arg_type == POINTER) {
        stuff.ptr =
            (it->it.ptr_array_iterator->
             array)[grpc_eval_integer(it->it.ptr_array_iterator->expression,
                                      i)];
      }
      if(arg_type == INTEGER) {
        x = (it->it.ptr_array_iterator->
             array)[grpc_eval_integer(it->it.ptr_array_iterator->expression,
                                      i)];
        stuff.i = *x;
      }
      break;
    default:
      ERRPRINTF("Unknown ITERATOR\n");
      stuff.i = 0;
  }

  return stuff;
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_initialize ( char *  config_file_name  ) 

Initialize the GridRPC system. This must be called before other grpc_ functions are called.

Parameters:
config_file_name -- the name of the configuration file (but currently we are ignoring it).
Returns:
GRPC_NO_ERROR if success. On error returns: GRPC_CONFIGFILE_NOT_FOUND: Specified configuration file not found GRPC_CONFIGFILE_ERROR: An error occurred parsing or processing the configuration file GRPC_ALREADY_INITIALIZED: grpc_initialize() was already called GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 421 of file gsgrpc.c.

{
  PROXY_COMPONENTADDR proxy_info;
  char *username=NULL, *tmp_host;
  int i;

#ifdef GS_SMART_GRIDSOLVE
  /*
   * Reads and increments the application file number.
   * This number is used to give each remote argument a
   * unique file name.
   */ 
  if(gs_smart_read_update_app_no_file("/tmp/gs_app_num", &smart_app_num)<0)
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

#endif



  /*
   * Repeated initializations return GRPC_ALREADY_INITIALIZED 
   */
  if(grpc_initialized == TRUE)
    GRPC_RETURN(GRPC_ALREADY_INITIALIZED, GRPC_NO_MINOR_ERROR);

  if(config_file_name)
    if(grpc_process_config_file(config_file_name) != GRPC_NO_ERROR)
      GRPC_RETURN(grpc_errno, GRPC_NO_MINOR_ERROR);

  GRPC_CLEAR_ERRORS();

  grpc_errno = GRPC_NO_ERROR;
  grpc_minor_errno = GRPC_NO_MINOR_ERROR;

  for(i = 0; i < MAX_GRPC_REQUESTS; i++) {
    grpc_outstanding_requests[i] = NULL;
    grpc_profile_info[i] = NULL;
    grpc_errors[i] = GRPC_NO_ERROR;
    grpc_minor_errors[i] = GRPC_NO_MINOR_ERROR;
  }

  /* Startup winsock in win32 */
  initialize_sockets();

  /*
   * Initialize the proxy library 
   */
  proxy_init("");

  if((username = gs_get_login_name())) {
    strncpy(grpc_user, username, GRPC_USER_INFO_LEN);
    grpc_user[GRPC_USER_INFO_LEN-1] = '\0';
    free(username);
  }
  else {
    strncpy(grpc_user, "unknown_user", GRPC_USER_INFO_LEN);
    grpc_user[GRPC_USER_INFO_LEN-1] = '\0';
  }

  tmp_host = gs_get_machine_name();
  if(!tmp_host) {
    strncpy(grpc_host, "unknown_host", GRPC_USER_INFO_LEN);
    grpc_host[GRPC_USER_INFO_LEN-1] = '\0';
    strncpy(grpc_domain, "unknown_domain", GRPC_USER_INFO_LEN);
    grpc_domain[GRPC_USER_INFO_LEN-1] = '\0';
  }
  else {
    char *p;

    strncpy(grpc_host, tmp_host, GRPC_USER_INFO_LEN);
    grpc_host[GRPC_USER_INFO_LEN-1] = '\0';
        
    if((p = strstr(grpc_host, "."))) {
      *p = '\0';
      strncpy(grpc_domain, p+1, GRPC_USER_INFO_LEN);
    }
    else
      strncpy(grpc_domain, "unknown_domain", GRPC_USER_INFO_LEN);

    grpc_domain[GRPC_USER_INFO_LEN-1] = '\0';

    free(tmp_host);
  }

  proxy_info = proxy_get_local_addr();

  proxy_cid_to_str(grpc_cid_str, proxy_info.ID);

  grpc_comm_cache = icl_hash_create(37, NULL);

  grpc_initialized = TRUE;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_iterator_t* grpc_int ( char *  s  ) 

Creates Interger Iterator

Parameters:
s -- Character string specifying the iteration
Returns:
Interger Iterator

Definition at line 5571 of file gsgrpc.c.

{
  grpc_iterator_t *it;

  if(!s) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return NULL;
  }

  it = (grpc_iterator_t *) calloc(1, sizeof(grpc_iterator_t));
  it->returned_type = INTEGER;
  it->specific =
      (grpc_specific_iterator_t *) calloc(1,
                                          sizeof(grpc_specific_iterator_t));
  it->specific->type = INT_ITERATOR;
  it->specific->it.int_iterator =
      (grpc_int_iterator_t *) calloc(1, sizeof(grpc_int_iterator_t));
  it->specific->it.int_iterator->expression = strdup(s);

  return it;
}

Here is the caller graph for this function:

grpc_iterator_t* grpc_int_array ( int *  array,
char *  expression 
)

Creates Interger Array Iterator

Parameters:
array -- Array to be iterarized
s -- Character string specifying the iteration
Returns:
Integer Array Iterator

Definition at line 5603 of file gsgrpc.c.

{
  grpc_iterator_t *it;

  if(!expression) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return NULL;
  }

  it = (grpc_iterator_t *) calloc(1, sizeof(grpc_iterator_t));
  it->returned_type = INTEGER;
  it->specific =
      (grpc_specific_iterator_t *) calloc(1,
                                          sizeof(grpc_specific_iterator_t));
  it->specific->type = INT_ARRAY_ITERATOR;
  it->specific->it.int_array_iterator =
      (grpc_int_array_iterator_t *) calloc(1,
                                           sizeof(grpc_int_array_iterator_t));
  it->specific->it.int_array_iterator->array = array;
  it->specific->it.int_array_iterator->expression = strdup(expression);

  return it;
}

Here is the caller graph for this function:

int grpc_local_X (  ) 

This function is used when there is code in the application that should be ignored during the task graph building phase. This is generally all operations which are performed on the client. All code that doesnt call a function in the grid_rpc library.

Returns:
1 if the current phase is an execution phase - The code in the scope of this function will be executed.
0 if the current phase is a mapping or task building phase - The code in the scope of this function will not be executed.

Definition at line 6375 of file gsgrpc.c.

                  {


#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase==GS_SMART_STANDARD_EXEC){
    return 1;
  }
  else if(smart_phase==GS_SMART_EXEC_TASK_FAIL){
    return 0;
  }
  else if(smart_phase==GS_SMART_MAP_FAIL){
    return 0;
  }
  else if(smart_phase==GS_SMART_TASK_DISCOVERY){
    return 0;
  }
  else if(smart_phase==GS_SMART_MAPPING){
   return 0; 
  }
  else if(smart_phase==GS_SMART_EXEC_CALLED_HANDLES){
    return 1;
  }
#else
  return 1;
#endif
  return 1;
}

char* grpc_minor_error_string ( grpc_error_t  minor_errno  ) 

For the last GRPC error (the minor error) return a string explaining the minor error.

Returns:
string representing the last minor error

Definition at line 1856 of file gsgrpc.c.

{
  if((minor_errno > GRPC_NO_MINOR_ERROR) &&
     (minor_errno < GRPC_LAST_MINOR_ERROR_CODE))
    return GRPC_MINOR_ERROR_MESSAGES[minor_errno-GRPC_NO_MINOR_ERROR];
  else
    return "";
}

Here is the caller graph for this function:

void grpc_perror ( char *  str  ) 

Prints a string explaining the last error to stderr.

Parameters:
str -- string to be printed before the error string.

Definition at line 1833 of file gsgrpc.c.

{
  /* check if this is a server-specific error code */
  if((grpc_minor_errno > GS_SVC_NO_ERROR) && 
     (grpc_minor_errno < GRPC_NO_MINOR_ERROR))
    fprintf(stderr, "%s: %s -- %s\n", str, grpc_error_string(grpc_errno),
       gs_service_error[grpc_minor_errno]);
  else if((grpc_minor_errno > GRPC_NO_MINOR_ERROR) &&
          (grpc_minor_errno < GRPC_LAST_MINOR_ERROR_CODE))
    fprintf(stderr, "%s: %s -- %s\n", str, grpc_error_string(grpc_errno),
       GRPC_MINOR_ERROR_MESSAGES[grpc_minor_errno-GRPC_NO_MINOR_ERROR]);
  else
    fprintf(stderr, "%s: %s\n", str, grpc_error_string(grpc_errno));
}

Here is the call graph for this function:

grpc_error_t grpc_probe ( grpc_sessionid_t  sessionID  ) 

Probe a previously submitted non-blocking request to determine if it has completed.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR if the specified request completed successfully. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_NOT_COMPLETED: Call has not completed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1224 of file gsgrpc.c.

{
  grpc_function_handle_t *handle;
  gs_server_t *srv;
  SOCKET sock;
  int tag;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionID])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(grpc_outstanding_requests[sessionID]->s_pid > 0) {
    if(gs_req_child_waitpid(grpc_outstanding_requests[sessionID], GS_WNOHANG) == 0) {
      /*
       * the child is still sending data to the parent 
       */
      GRPC_RETURN(GRPC_NOT_COMPLETED, GRPC_NO_MINOR_ERROR);
    }
  }

  handle = grpc_outstanding_requests[sessionID]->handle;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);

  srv = handle->server_list[handle->srv_idx];

  sock = gs_connect_to_host(srv->componentid, srv->ipaddress, srv->port,
                            srv->proxyip, srv->proxyport);

  if(sock == INVALID_SOCKET)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SERVER_CONNECTION);

  if((gs_send_tag(sock, GS_PROT_PROBE_REQUEST) < 0) ||
     (gs_send_string(sock, VERSION) < 0)) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  }

  if(gs_recv_tag(sock, &tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  }
    
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;
    
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
  } 

  if(gs_send_string(sock, grpc_outstanding_requests[sessionID]->request_id) < 0)
    goto probe_failure;

  if(gs_recv_tag(sock, &tag) < 0)
    goto probe_failure;

  proxy_close(sock);

  switch (tag) {
    case GS_PROT_OK:
      GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
    case GS_SVC_ERR_NOT_FINISHED:
      GRPC_RETURN(GRPC_NOT_COMPLETED, GRPC_NO_MINOR_ERROR);
    default:
      ERRPRINTF("Probe failed: %s\n", gs_service_error[tag]);
      if(gs_notify_agent_of_failure(handle, 
           grpc_outstanding_requests[sessionID]->request_id) < 0)
        ERRPRINTF("Warning: failed to notify agent of server failure.\n");
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, tag);
  }

probe_failure:
  proxy_close(sock);
  if(gs_notify_agent_of_failure(handle, 
       grpc_outstanding_requests[sessionID]->request_id) < 0)
    ERRPRINTF("Warning: failed to notify agent of server failure.\n");
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
  
  /*
   * shouldn't reach here 
   */
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_probe_ft ( grpc_sessionid_t  sessionID  ) 

Probe a previously submitted non-blocking request to determine if it has completed. This is the fault tolerant version of grpc_probe(). If we probe the request and detect that it failed, then we resubmit the job to another server and return FALSE.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR if the specified request completed successfully. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_NOT_COMPLETED: Call has not completed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4738 of file gsgrpc.c.

{
  grpc_function_handle_t *handle;
  grpc_error_t retval;
  int c; 

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  retval = grpc_probe(sessionID);

  /*
   * if probe returns 
   */

  if((retval == GRPC_NO_ERROR) || (retval == GRPC_NOT_COMPLETED))
    GRPC_RETURN(retval, grpc_minor_errno);

  handle = grpc_outstanding_requests[sessionID]->handle;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  /*
   * if we reach this point, then the call to grpc_probe detected a failure
   * and we should resubmit the request to another server. 
   */

  for(c = 0; c < handle->num_servers; c++) {
    if(gs_resubmit_common(sessionID) == GRPC_NO_ERROR)
      GRPC_RETURN(GRPC_NOT_COMPLETED, GRPC_NO_MINOR_ERROR);

    if(handle->num_servers == 0)
      break;

    handle->srv_idx = (handle->srv_idx + 1) % handle->num_servers;
  }

  handle->srv_idx = 0;

  GRPC_RETURN(GRPC_SERVER_NOT_FOUND, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_probe_or ( grpc_sessionid_t *  idArray,
size_t  length,
grpc_sessionid_t *  idPtr 
)

Probe for any of the previously submitted non-blocking requests in 'idArray'.

Parameters:
idArray -- array of session IDs to wait for
length -- number of elements in idArray
idPtr -- on return, this is set to the session ID of the job that completed.
Returns:
GRPC_NO_ERROR if one of the requests in idArray has completed successfully. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: a session ID in idArray is not valid GRPC_NONE_COMPLETED: No calls in idArray have completed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1335 of file gsgrpc.c.

{   
  gs_service_error_enum_t retval_minor;
  grpc_error_t retval;
  int i; 

  *idPtr = GRPC_SESSIONID_VOID;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);
  
  /*
   * first validate the numbers 
   */
  for(i = 0; i < (int)length; i++)
    if((idArray[i] < 0) || (idArray[i] >= MAX_GRPC_REQUESTS))
      GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  retval = GRPC_NONE_COMPLETED;
  retval_minor = GRPC_NO_MINOR_ERROR;

  for(i = 0; i < (int)length; i++) {
    grpc_sessionid_t s = idArray[i];
      
    if(grpc_outstanding_requests[s] != NULL) {
      grpc_error_t r;

      r = grpc_probe(s);

      if(r == GRPC_NO_ERROR) {
        *idPtr = s;
        GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
      }
      else if(r != GRPC_NOT_COMPLETED) {
        retval = r;
        retval_minor = grpc_minor_errno;
      }
    }
  }

  GRPC_RETURN(retval, retval_minor);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_process_config_file ( char *  config_file_name  ) 

Reads and processes the configuration file.

Parameters:
config_file_name -- the name of the configuration file (but currently we are ignoring it).
Returns:
GRPC_NO_ERROR if success. On error returns: GRPC_CONFIGFILE_NOT_FOUND: Specified configuration file not found GRPC_CONFIGFILE_ERROR: An error occurred parsing or processing the configuration file GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 370 of file gsgrpc.c.

{
  gs_info_t *attr_list = NULL;
  gs_struct_stat stbuf;

  if(!config_file_name)
    GRPC_RETURN(GRPC_CONFIGFILE_NOT_FOUND, GRPC_NO_MINOR_ERROR);

  if(gs_stat(config_file_name, &stbuf) < 0)
    GRPC_RETURN(GRPC_CONFIGFILE_NOT_FOUND, GRPC_NO_MINOR_ERROR);

  if(gs_parse_config_file(config_file_name, &attr_list) != 0)
    GRPC_RETURN(GRPC_CONFIGFILE_ERROR, GRPC_NO_MINOR_ERROR);

  if(attr_list) {
    gs_info_t *p;

    for(p = attr_list; p != NULL; p = p->next) {
      if(!strcasecmp(p->type, "MEASURE_COMM"))
        grpc_measure_comm = strcasecmp(p->value, "y") == 0;
      else if(!strcasecmp(p->type, "MEASURE_COMM_NUM_SERVERS"))
        grpc_measure_comm_num_servers = atoi(p->value);
      else if(!strcasecmp(p->type, "MEASURE_COMM_CACHE_TTL"))
        grpc_measure_comm_cache_ttl = atoi(p->value);
      else if(!strcasecmp(p->type, "MEASURE_COMM_TIME_THRESH"))
        grpc_measure_comm_time_thresh = atof(p->value);
    }
  }

  gs_free_infolist(attr_list);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_profile ( grpc_profile_t *  prof  ) 

This routine enables client profiling. The profiling information will be stored in the given structure.

Parameters:
prof -- the profiling structure in which to store the information
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4623 of file gsgrpc.c.

{
#ifdef GS_PROFILING
  grpc_profile_next = prof;
  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
#else

  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_PROFILING_NOT_ENABLED);
#endif
}

Here is the caller graph for this function:

grpc_iterator_t* grpc_ptr_array ( void **  array,
char *  expression 
)

Creates Pointer Array Iterator

Parameters:
array -- Array to be iterarized
s -- Character string specifying the iteration
Returns:
Pointer Array Iterator

Definition at line 5637 of file gsgrpc.c.

{
  grpc_iterator_t *it;

  if(!expression) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return NULL;
  }

  it = (grpc_iterator_t *) calloc(1, sizeof(grpc_iterator_t));
  it->returned_type = POINTER;
  it->specific =
      (grpc_specific_iterator_t *) calloc(1,
                                          sizeof(grpc_specific_iterator_t));
  it->specific->type = PTR_ARRAY_ITERATOR;
  it->specific->it.ptr_array_iterator =
      (grpc_ptr_array_iterator_t *) calloc(1,
                                           sizeof(grpc_ptr_array_iterator_t));
  it->specific->it.ptr_array_iterator->array = array;
  it->specific->it.ptr_array_iterator->expression = strdup(expression);

  return it;
}

Here is the caller graph for this function:

static int grpc_request_destruct ( grpc_request_t *  req  ) 

This destroys a grpc_request_t structure.

Parameters:
req -- the request structure to be destroyed.
Returns:
0 on success, -1 on failure.

Definition at line 4280 of file gsgrpc.c.

{
  if(!req)
    return -1;

  /*
   * don't free handle since it's only a pointer to the user's data. we'll
   * let them free it. 
   */
  if(req->request_id)
    free(req->request_id);
  req->request_id = NULL;
  if(req->problem)
    gs_free_problem(req->problem);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int grpc_request_destruct_free_clear ( grpc_sessionid_t  sessionId  ) 

Clears an entry in the grpc outstanding request list, and call the request structure destruct. Note, the request->handle is not destructed.

Parameters:
sessionId -- the entry to be cleared, NB if an invalid sessionID is sent, the call succeeds with no error reported
Returns:
-1 on failure, 0 otherwise.

Definition at line 4310 of file gsgrpc.c.

{
  int rc = -1;

  if((sessionId < 0) || (sessionId >= MAX_GRPC_REQUESTS))
    return 0;

  rc = grpc_request_destruct(grpc_outstanding_requests[sessionId]);
  if(rc != 0)
    return -1;
  if(grpc_outstanding_requests[sessionId])
    free(grpc_outstanding_requests[sessionId]);
  grpc_outstanding_requests[sessionId] = NULL;
  grpc_profile_info[sessionId] = NULL;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_retrieve ( char *  request_str,
  ... 
)

Retrieve results from a serialized request. When retrieving results in this way, the arguments must be passed again becuase we have no way to know where to store the results since this process may not have ever submitted the initial request. The arguments should be specified in the same way as they were when the intial call was made.

Parameters:
request_str -- the serialized request
... -- the arguments (as specified when the call was originally made)
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 2259 of file gsgrpc.c.

{
  gs_service_error_enum_t save_minor_errno;
  grpc_request_t *req;
  gs_va_list argptr;
  grpc_error_t status;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  va_start(argptr.args, request_str);

  req = (grpc_request_t *) malloc(sizeof(grpc_request_t));

  if(!req)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  if(grpc_deserialize_request(request_str, req) != GRPC_NO_ERROR)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);

  if(gs_sender_compute_arg_sizes(&argptr, NULL, req->problem,
       grpc_client_lang, grpc_client_major) < 0)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);

  status = gs_wait_common(req);
  save_minor_errno = grpc_minor_errno;

  grpc_function_handle_destruct(req->handle);
  free(req->handle);
  grpc_request_destruct(req);
  free(req);

  GRPC_RETURN(status, save_minor_errno);
}

Here is the call graph for this function:

grpc_error_t grpc_send_farming_request ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sid,
grpc_iterator_t **  iterator_array,
int  nb_args 
)

Sends the farming request to the server

Parameters:
handle -- handle to the request
sid -- on return, contains the session ID
iterator_array -- Array of iterators for each argument
nb_args -- number of arguments in the farming call
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5295 of file gsgrpc.c.

{
  gs_service_error_enum_t save_minor_errno;
  grpc_arg_stack *stack = NULL;
  gs_argument_t *argp = NULL;
  grpc_error_t status;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!iterator_array)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_FARM_NULL_ITERATOR);

  status =
      grpc_setup_farming_args(handle->problem_desc, iterator_array, nb_args);
  if(status != GRPC_NO_ERROR)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_FARM_SETUP_ARGS_FAILED);

  /*
   * Creating Stack 
   */
  stack = grpc_arg_stack_new(nb_args);
  if(!stack)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_FARM_CREATE_STACK_FAILED);

  for(argp = handle->problem_desc->arglist; argp != NULL; argp = argp->next) {
    if(grpc_arg_stack_push_arg(stack, argp->data) < 0)
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_FARM_CREATE_STACK_FAILED);
  }

  /*
   * Calling solve routine with stack interface 
   */
  status = grpc_call_arg_stack_async_ft(handle, sid, stack);
  save_minor_errno = grpc_minor_errno;
  grpc_arg_stack_destruct(stack);
  GRPC_RETURN(status, save_minor_errno);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_serialize_request ( grpc_sessionid_t  sessionID,
char **  str 
)

Serializes a previously submitted request to a string. This allows saving the request information to disk and retrieving it later (even from a different process or machine).

Parameters:
sessionId -- the session ID of the previously submitted request.
str -- string into which the serialized request will be placed. the user does not need to allocate space for the string.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 2046 of file gsgrpc.c.

{
  char *server_str, *problem_str;
  grpc_function_handle_t *handle;
  grpc_request_t *req;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  req = grpc_outstanding_requests[sessionID];

  if(!req)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  handle = req->handle;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  if(gs_encode_server(&server_str, handle->server_list[handle->srv_idx]) < 0)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SERVER_ENCODE);

  if(!server_str)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);

  if(gs_encode_problem(&problem_str, handle->problem_desc) < 0)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_PROBLEM_ENCODE);

  if(!problem_str) {
    free(server_str);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
  }

  *str =
      dstring_sprintf
      ("<request id=\"%s\">\n  <handle func_name=\"%s\">\n%s\n%s\n  </handle>\n</request>\n",
       req->request_id, handle->func_name, server_str, problem_str);

  free(server_str);
  free(problem_str);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

grpc_error_t grpc_set_client_language ( int  lang  ) 

Sets the language the client code is implemented in.

Parameters:
lang -- either GS_CALL_FROM_C or GS_CALL_FROM_FORTRAN
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4707 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((lang != GS_CALL_FROM_C) && (lang != GS_CALL_FROM_FORTRAN))
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_LANG);

  grpc_client_lang = lang;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the caller graph for this function:

grpc_error_t grpc_set_client_major ( char *  maj  ) 

This routine sets the major (row- or column-wise) used by the client. Takes as input "[Rr]*" or "[Cc]*"

Parameters:
maj -- string representing the matrix storage format used by the client ("[Rr]*" for row-major or "[Cc]*" for column-major).
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4649 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!maj)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_MAJOR);

  if((maj[0] == 'R') || (maj[0] == 'r')) {
    grpc_client_major = 'r';
    grpc_user_set_major = TRUE;
  }
  else if((maj[0] == 'C') || (maj[0] == 'c')) {
    grpc_client_major = 'c';
    grpc_user_set_major = TRUE;
  }
  else
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_INVALID_MAJOR);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the caller graph for this function:

grpc_error_t grpc_set_criteria ( grpc_function_handle_t *  handle,
char *  c 
)

Sets the server/resource selection criteria string.

Parameters:
handle -- The function handle whose criteria should be updated.
c -- The criteria string to be matched by the agent. This can be NULL, which causes any previously set criteria string to be cleared.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 555 of file gsgrpc.c.

{
  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);

  if(c) {
    handle->criteria = strdup(c);
    if(!handle->criteria) {
      ERRPRINTF("Can't allocate memory, strdup failed\n");
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_OUT_OF_MEMORY);
    }
  }
  else {
    /*
     * Client has set criteria to NULL.  If there was already some criteria
     * set, then free it first. 
     */
    if(handle->criteria)
      free(handle->criteria);

    handle->criteria = NULL;
  }

  /*
   * since the criteria have changed, request that the next call using this
   * handle gets a new binding (i.e. server list). 
   */
  handle->bind_servers_at_call_time = 1;

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the caller graph for this function:

grpc_error_t grpc_set_default_major ( char *  maj  ) 

Sets the default major to be used in case it is not explicitly specified.

Parameters:
maj -- string representing the matrix storage format used by the client ("[Rr]*" for row-major or "[Cc]*" for column-major).
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4685 of file gsgrpc.c.

{
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!grpc_user_set_major)
    return grpc_set_client_major(maj);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_setup_farming_args ( gs_problem_t *  problem,
grpc_iterator_t **  it_array,
int  nb_args 
)

Sets the farming argument for each request in the farming call

Parameters:
problem -- problem structure containing the problem information
it_array -- Iterator array of iterator for each argument
nb_args -- Number of arguments in the farming call
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 5350 of file gsgrpc.c.

{
  void *dataptr = NULL;
  gs_argument_t *argp = NULL;
  int i = 0;
  grpc_void_star_or_int_t *stackarray;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if(!problem || !it_array)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);

  /*
   * Creating Array from Iterators 
   */
  if(grpc_generate_array_from_iterators
     (problem, &stackarray, it_array, nb_args) != GRPC_NO_ERROR)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);

  /*
   * For each argument, check datatype, and attach a dataptr to the arg->data 
   */
  for(argp = problem->arglist, i = 0; argp != NULL; argp = argp->next, i++) {
    switch (argp->datatype) {
      case GS_DOUBLE:
        dataptr = (double *) calloc(1, sizeof(double));
        if(!dataptr)
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
        dataptr = (double *) (stackarray[i].ptr);
        break;
      case GS_SCOMPLEX:
        dataptr = (gs_scomplex *) calloc(1, sizeof(gs_scomplex));
        if(!dataptr)
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
        dataptr = (gs_scomplex *) (stackarray[i].ptr);
        break;
      case GS_DCOMPLEX:
        dataptr = (gs_dcomplex *) calloc(1, sizeof(gs_dcomplex));
        if(!dataptr)
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
        dataptr = (gs_dcomplex *) (stackarray[i].ptr);
        break;
      case GS_INT:
        dataptr = (int *) calloc(1, sizeof(int));
        if(!dataptr)
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
        if(argp->objecttype == GS_SCALAR)
          ((int *) dataptr)[0] = stackarray[i].i;
        else
          dataptr = (int *) (stackarray[i].ptr);
        break;
      case GS_FLOAT:
        dataptr = (float *) calloc(1, sizeof(float));
        if(!dataptr)
          GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
        /*
         * if (argp->inout == GS_IN || argp->inout == GS_INOUT) 
         */
        dataptr = (float *) (stackarray[i].ptr);
        break;
      case GS_CHAR:
        dataptr = (char *) calloc(1, sizeof(char));
        dataptr = (char *) (stackarray[i].ptr);
        break;
      default:
        ERRPRINTF("This datatype is not handled yet\n");
        GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }
    argp->data = dataptr;
  }

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_wait ( grpc_sessionid_t  sessionID  ) 

Block until a previously submitted non-blocking request completes.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1531 of file gsgrpc.c.

{
#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase==GS_SMART_EXEC_TASK_FAIL){
    return GRPC_NO_ERROR;
  }

#endif
  gs_service_error_enum_t save_minor_errno;
  grpc_error_t status;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionID])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  status = gs_wait_common(grpc_outstanding_requests[sessionID]);
  save_minor_errno = grpc_minor_errno;

#ifdef GS_PROFILING
  if(grpc_profile_info[sessionID]) {
    GRPC_TIMER_STOP(grpc_profile_info[sessionID]);
    grpc_profile_info[sessionID]->recv_output =
        GRPC_TIMER_ELAPSED(grpc_profile_info[sessionID]);
  }
#endif

  if(status != GRPC_NO_ERROR) {
    grpc_last_failed_idx = 0;
    grpc_last_failed_sid[grpc_last_failed_idx] = sessionID;
  }
  else 
    grpc_last_failed_idx = -1;

  grpc_request_destruct(grpc_outstanding_requests[sessionID]);
  free(grpc_outstanding_requests[sessionID]);
  grpc_outstanding_requests[sessionID] = NULL;
  grpc_profile_info[sessionID] = NULL;

  GRPC_RETURN(status, save_minor_errno);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_wait_all ( void   ) 

Block until all previously submitted non-blocking requests have completed.

Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1730 of file gsgrpc.c.

{
  grpc_sessionid_t tmp_sid[MAX_GRPC_REQUESTS];
  int tmp_idx, saw_failure = FALSE;
  grpc_sessionid_t sid = 0;
  grpc_error_t r;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  tmp_idx = -1;

  for(;;) {
    r = grpc_wait_any(&sid);

    if(r != GRPC_NO_ERROR) {

      if(sid >= 0) {
        tmp_idx++;
        tmp_sid[tmp_idx] = sid;
      }

      /* if there are no more jobs to wait for */
      if(r == GRPC_OTHER_ERROR_CODE) {

        /* copy failed session IDs to the global array */
        grpc_last_failed_idx = tmp_idx;
        memcpy(grpc_last_failed_sid, tmp_sid, (tmp_idx+1) * sizeof(*tmp_sid));

        GRPC_RETURN(saw_failure ? GRPC_SESSION_FAILED : GRPC_NO_ERROR,
          grpc_minor_errno);
      }

      saw_failure = TRUE;
    }
  }

  /* should not reach here */
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

grpc_error_t grpc_wait_and ( grpc_sessionid_t *  idArray,
size_t  length 
)

Block until all of the previously submitted non-blocking requests in 'idArray' have completed.

Parameters:
idArray -- array of session IDs to wait for
length -- number of elements in idArray
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1593 of file gsgrpc.c.

{
  int i, tmp_idx, requests_remaining = TRUE, saw_failure = FALSE;
  grpc_sessionid_t tmp_sid[MAX_GRPC_REQUESTS];

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  tmp_idx = -1;

  /*
   * first validate the numbers 
   */
  for(i = 0; i < (int)length; i++)
    if((idArray[i] < 0) || (idArray[i] >= MAX_GRPC_REQUESTS))
      GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  while(requests_remaining) {
    requests_remaining = FALSE;

    for(i = 0; i < (int)length; i++) {
      grpc_sessionid_t s = idArray[i];

      if(grpc_outstanding_requests[s] != NULL) {
        requests_remaining = TRUE;

        /* if the job is no longer running (i.e. it either successfully
         * completed or it failed) call wait and check the error status.
         */

        if(grpc_probe(s) != GRPC_NOT_COMPLETED) {
          if(grpc_wait(s) != GRPC_NO_ERROR) {
            saw_failure = TRUE;
            grpc_errors[s] = grpc_errno;
            grpc_minor_errors[s] = grpc_minor_errno;
            tmp_idx++;
            tmp_sid[tmp_idx] = s;
          }
        }
      }
    }

    sleep(1);
  }

  /* copy failed session IDs to the global array */
  grpc_last_failed_idx = tmp_idx;
  memcpy(grpc_last_failed_sid, tmp_sid, (tmp_idx+1) * sizeof(*tmp_sid));

  GRPC_RETURN(saw_failure ? GRPC_SESSION_FAILED : GRPC_NO_ERROR,
     GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_wait_any ( grpc_sessionid_t *  idPtr  ) 

Block until any one of the previously submitted non-blocking requests has completed.

Parameters:
idPtr -- on return, this is set to the session ID of the job that completed.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1786 of file gsgrpc.c.

{
  int i, jobCount = 0;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  for(;;) {
    for(i = 0; i < MAX_GRPC_REQUESTS; i++)
      if(grpc_outstanding_requests[i] != NULL) {
        /* if the job is no longer running (i.e. it either successfully
         * completed or it failed) call wait and check the error status.
         */

        if(grpc_probe(i) != GRPC_NOT_COMPLETED) {
          grpc_error_t r = grpc_wait(i);

          *idPtr = i;

          if(r != GRPC_NO_ERROR) {
            grpc_errors[i] = grpc_errno;
            grpc_minor_errors[i] = grpc_minor_errno;
          }

          GRPC_RETURN(r, grpc_minor_errno);
        }

        jobCount++;
      }

    if(jobCount == 0) {
      *idPtr = -1;
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }

    sleep(1);
  }

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_wait_ft ( grpc_sessionid_t  sessionID  ) 

Block until a previously submitted non-blocking request completes. This is the fault tolerant version of grpc_wait(). If we wait for the job and detect that it failed, then we resubmit the job to another server and wait for that job to complete.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4805 of file gsgrpc.c.

{
  grpc_function_handle_t *handle;
  int c;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(grpc_wait(sessionID) == GRPC_NO_ERROR)
    return GRPC_NO_ERROR;

  handle = grpc_outstanding_requests[sessionID]->handle;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  /*
   * if we reach this point, then the call to grpc_wait detected a failure
   * and we should resubmit the request to another server. 
   */

  for(c = 0; c < handle->num_servers; c++) {
    if(gs_resubmit_common(sessionID) == GRPC_NO_ERROR) {

      /*
       * ok, we were able to resubmit the job successfully, so now we wait
       * for it to complete.  if this wait fails, we keep attempting to
       * resubmit until no more servers remain. 
       */
      if(grpc_wait(sessionID) == GRPC_NO_ERROR)
        return GRPC_NO_ERROR;
    }

    if(handle->num_servers == 0)
      break;
    handle->srv_idx = (handle->srv_idx + 1) % handle->num_servers;
  }

  handle->srv_idx = 0;
  GRPC_RETURN(GRPC_SERVER_NOT_FOUND, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t grpc_wait_or ( grpc_sessionid_t *  idArray,
size_t  length,
grpc_sessionid_t *  idPtr 
)

Block until any one of the previously submitted non-blocking requests in 'idArray' has completed.

Parameters:
idArray -- array of session IDs to wait for
length -- number of elements in idArray
idPtr -- on return, this is set to the session ID of the job that completed.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 1664 of file gsgrpc.c.

{
  int i, jobCount = 0;

  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  /*
   * first validate the numbers 
   */
  for(i = 0; i < (int)length; i++)
    if((idArray[i] < 0) || (idArray[i] >= MAX_GRPC_REQUESTS))
      GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  for(;;) {

    for(i = 0; i < (int)length; i++) {
      grpc_sessionid_t s = idArray[i];

      if(grpc_outstanding_requests[s] != NULL) {
        /* if the job is no longer running (i.e. it either successfully
         * completed or it failed) call wait and check the error status.
         */

        if(grpc_probe(s) != GRPC_NOT_COMPLETED) {
          grpc_error_t r;

          *idPtr = s;

          r = grpc_wait(s);

          if(r != GRPC_NO_ERROR) {
            grpc_errors[s] = grpc_errno;
            grpc_minor_errors[s] = grpc_minor_errno;
          }

          GRPC_RETURN(r, grpc_minor_errno);
        }

        jobCount++;
      }
    }

    if(jobCount == 0) {
      *idPtr = -1;
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }

    sleep(1);
  }

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

static grpc_error_t gs_call_common ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
gs_va_list *  argptr,
void **  argstack,
int  blocking 
) [static]

This is common code for all the grpc_call*() functions. Here we do the real work.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request (only for non-blocking requests)
argptr -- va_list of the arguments for this call. one of argptr or argstack should be non-NULL but not both.
argstack -- array of pointers to the args for this call. one of argptr or argstack should be non-NULL but not both.
blocking -- if TRUE, this function will not return until the remote procedure has completed and all results are retrieved. if FALSE, this function returns after the input arguments have been sent to the remote server.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 3556 of file gsgrpc.c.

{
  int tag, agent_taskid;
  SOCKET sock;
  int my_dsig;
  char *msg, *request_id = NULL;
  gs_server_t *srv;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  grpc_minor_errno = GRPC_NO_MINOR_ERROR;


#ifdef GS_SMART_GRIDSOLVE
/*
 * when the user has explicitly speficied the number of tasks to build
 * check if there are still tasks to be built. if so set the phase to building.
 */
  if(group_type==GS_SMART_EXPLICIT_GROUP){
    if( gs_smart_get_nb_auto_tasks_left_to_build()>0 ){
      smart_phase=GS_SMART_TASK_DISCOVERY;
    }
  }

 /*
  * if we are still executing mapped tasks 
  * (i.e. when nb_mapped_tasks_executed<total_nb_mapped_tasks)
  * then embed the mapping information into this task handle.
  * If smart_phase has been set to GS_SMART_STANDARD_EXEC
  * then it means the task has already failed execution on 
  * a different server. Therefore we do not implement
  * the mapping for this task and execute it in the
  * standard gs protocol. 
  */

 if((nb_mapped_tasks_executed<total_nb_mapped_tasks) && 
    (smart_phase!=GS_SMART_STANDARD_EXEC) && (smart_phase!=GS_SMART_TASK_DISCOVERY)){
   if(gs_smart_mg_embed_mapping(handle, nb_mapped_tasks_executed)<0){
     ERRPRINTF("SMART : Error embedding mapping\n");
     return -1;
   }
 }
#endif

#ifdef GS_PROFILING
  if(grpc_profile_next) {
    /*
     * clear profiling info 
     */
    memset(grpc_profile_next, 0, sizeof(grpc_profile_t));

    GRPC_TIMER_START(grpc_profile_next);
  }
#endif



#ifdef GS_PROFILING
  if(grpc_profile_next) {
    /*
     * clear profiling info 
     */
    memset(grpc_profile_next, 0, sizeof(grpc_profile_t));

    GRPC_TIMER_START(grpc_profile_next);
  }
#endif

  my_dsig = pvmgetdsig();

  /*
   * Check if the servers are to be bound now.  If so talk with the agent.
   * This variable was set when the handle was initialized 
   */
 
#ifdef GS_SMART_GRIDSOLVE

/*
 * if the current phase is the building phase, store the handle and exit
 * the gs_call_common_function
 */
  if( ( smart_phase==GS_SMART_TASK_DISCOVERY ) ){       
    /*
     * If the bind_servers_at_call_time parameter has been specified
     * i.e. the user has requested that the task gets mapped at 
     * run-time, then the handle's problem desc will not be initialised
     * for the task discovery phase. In this case we get the problem
     * description here.  And then when the task is called for execution
     * the problem description will not be retrieved like it normally would.
     * 
     */ 
    if(handle->bind_servers_at_call_time == 1) {
      char *tmp_name;

      /*
       * get_server_mapping will over-write both server_list and func_name.  we 
       * can go ahead and free the server_list now, but we will have to save a
       * pointer to func_name and free it afterwards. 
       */
      gs_free_handle_server_list(handle);
      tmp_name = handle->func_name;
      handle->func_name = NULL;

      /*
       * Get server mapping is a full transaction with the agent that can can
       * include the input arguments if they are provided 
       */
      if(gs_get_server_mapping(tmp_name, handle, argptr, argstack,
            my_dsig, grpc_client_lang, grpc_client_major) < 0) {
        /* restore the handle's function name */
        handle->func_name = tmp_name;
        handle->valid_mapping=0;
        GRPC_RETURN(grpc_errno, grpc_minor_errno);
      }
      handle->valid_mapping=1;
      free(tmp_name);

      /*
       * Keep this binding from now on, so that fault tolerance works correctly 
       */
      handle->bind_servers_at_call_time = 0;
    }
    
    if(gs_smart_store_handle(handle, sessionId, argptr, blocking, grpc_client_lang, grpc_client_major, group_type)<0){
       ERRPRINTF("SMART : Error storing handle \n");
       return -1;
    }

    /*
     * if the user has explicitly specified and the last task in that group has just
     * been built, then execute stored handles and exit the gs_call_common function.
     */
    if(group_type==GS_SMART_EXPLICIT_GROUP){
      if( gs_smart_get_nb_auto_tasks_left_to_build()==0 ){
         
        smart_phase=GS_SMART_EXEC_STORED_HANDLES;    
       /*
        TODO : reintroduce execute stored handles for explicit calls to gs_smart_map
        */
       smart_phase=GS_SMART_STANDARD_EXEC;
     }
   }
   handle->valid_mapping=1;
   return 0;
 }

 if(smart_phase==GS_SMART_STANDARD_EXEC){
   if(handle->bind_servers_at_call_time == 1) {
     char *tmp_name;

     /*
      * get_server_mapping will over-write both server_list and func_name.  we 
      * can go ahead and free the server_list now, but we will have to save a
      * pointer to func_name and free it afterwards. 
      */
     gs_free_handle_server_list(handle);
     tmp_name = handle->func_name;
     handle->func_name = NULL;

     /*
      * Get server mapping is a full transaction with the agent that can can
      * include the input arguments if they are provided 
      */
     if(gs_get_server_mapping(tmp_name, handle, argptr, argstack,
           my_dsig, grpc_client_lang, grpc_client_major) < 0) {
       /* restore the handle's function name */
       handle->func_name = tmp_name;
       GRPC_RETURN(grpc_errno, grpc_minor_errno);
     }

     free(tmp_name);

     /*
      * Keep this binding from now on, so that fault tolerance works correctly 
      */
     handle->bind_servers_at_call_time = 0;
   }  
   handle->valid_mapping=1;
 } 



#else
 if(handle->bind_servers_at_call_time == 1) {
    char *tmp_name;

    /*
     * get_server_mapping will over-write both server_list and func_name.  we 
     * can go ahead and free the server_list now, but we will have to save a
     * pointer to func_name and free it afterwards. 
     */
    gs_free_handle_server_list(handle);
    tmp_name = handle->func_name;
    handle->func_name = NULL;

    /*
     * Get server mapping is a full transaction with the agent that can can
     * include the input arguments if they are provided 
     */
    if(gs_get_server_mapping(tmp_name, handle, argptr, argstack,
          my_dsig, grpc_client_lang, grpc_client_major) < 0) {
      /* restore the handle's function name */
      handle->func_name = tmp_name;
      GRPC_RETURN(grpc_errno, grpc_minor_errno);
    }

    free(tmp_name);

    /*
     * Keep this binding from now on, so that fault tolerance works correctly 
     */
    handle->bind_servers_at_call_time = 0;
  }
#endif

#ifdef GS_SMART_GRIDSOLVE
/*
  if(!handle->valid_mapping){
      GRPC_RETURN(grpc_errno, grpc_minor_errno);
  }
*/
#endif
  srv = handle->server_list[handle->srv_idx];

#ifdef GS_PROFILING
  if(grpc_profile_next) {
    GRPC_TIMER_STOP(grpc_profile_next);
    grpc_profile_next->agent_comm = GRPC_TIMER_ELAPSED(grpc_profile_next);
    GRPC_TIMER_START(grpc_profile_next);
  }
#endif

  /* compare greater than 0 here; elsewhere greater than 1.  this is because
   * at this point we haven't incremented yet.
   */
  if(handle->num_calls > 0)
    agent_taskid = -1;
  else
    agent_taskid = handle->agent_taskid;


#ifdef GS_SMART_GRIDSOLVE

printf("\n\n\n\n");
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
printf("Executing task %s on server %s:%d\n", handle->problem_desc->name, srv->hostname, srv->port);

#endif

  sock = gs_connect_to_host(srv->componentid, srv->ipaddress, srv->port,
                            srv->proxyip, srv->proxyport);



/*
 * Implementing fault tolerance for SmartGridSolve
 */ 

 if(sock == INVALID_SOCKET){
#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase!=GS_SMART_STANDARD_EXEC){
    smart_phase=GS_SMART_EXEC_TASK_FAIL;

    /*
     * SmartGridSolve fault tolerance
     * Failed to connect to server
     * Sending failed server to agent to be removed from pm
     */

  printf("SMART: Server %s has failed during execution .\n", srv->hostname);
     if((sock = gs_connect_to_agent()) == INVALID_SOCKET)
       GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_AGENT_NOT_SET);


  if((gs_send_tag(sock, GS_SMART_FAULT_UPDATE_PM) < 0) ||
     (gs_send_string(sock, VERSION) < 0) ||
     (gs_recv_tag(sock, &tag) < 0))
    goto error_communication_failed;
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH) {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_VERSION_MISMATCH);
    } else {
      GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
    }
  }


    char *srv_str = NULL;
    if((gs_encode_server(&srv_str, srv) < 0) ||
       (gs_send_string(sock, srv_str) < 0)) {
      FREE(srv);
      DBGPRINTF("Failed to send server list \n");
      return -1;
    }

    FREE(srv_str);

    

  printf("SMART: Server %s has been removed from network graph .\n", srv->hostname);
  printf("SMART: Remapping group of tasks.\n");


  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;

 


    return GRPC_NO_ERROR;
  }
  else{
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_SERVER_CONNECTION);
  } 
#else 
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_SERVER_CONNECTION);
#endif
  }

  if(gs_encode_problem_solve_request(&msg, handle->func_name, 
     grpc_user, grpc_host, grpc_domain, grpc_cid_str, my_dsig, 
     agent_taskid, srv->score) < 0) {
    grpc_minor_errno = GRPC_SOLVE_REQ_ENCODE;
    goto error_client_internal_error;
  }

  if(handle->problem_desc == NULL)
    tag = GS_PROT_PROBLEM_SOLVE_ASSIGNED;
  else
    tag = GS_PROT_PROBLEM_SOLVE;

  if((gs_send_tag(sock, tag) < 0) ||
     (gs_send_string(sock, VERSION) < 0))
    goto error_communication_failed;

  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;
  
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;

    goto error_client_internal_error;
  }

  tag = (blocking) ? GS_PROT_BLOCKING : GS_PROT_NONBLOCKING;

  if(gs_send_tag(sock, tag) < 0)
    goto error_communication_failed;

  if(gs_send_string(sock, msg) < 0)
    goto error_communication_failed;

  FREE(msg);

  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;

  if(tag != GS_PROT_OK) {
    ERRPRINTF("Error occured\n");
    switch (tag) {
      case GS_SVC_ERR_EXEC:
        proxy_close(sock);
        GRPC_RETURN(GRPC_FUNCTION_NOT_FOUND, GRPC_NO_MINOR_ERROR);
      default:
        ERRPRINTF("%s\n", gs_service_error[tag]);
        proxy_close(sock);
        GRPC_RETURN(GRPC_OTHER_ERROR_CODE, tag);
    }
  }

  if(gs_recv_string(sock, &request_id) < 0)
    goto error_communication_failed;

  if(handle->problem_desc == NULL) {
    /*
     * this must be an assigned server request, so get the problem desc from 
     * the server.  also since the client won't know what architecture the
     * server is, the server will send its data signature now. 
     */
    if(gs_recv_string(sock, &msg) < 0)
      goto error_communication_failed;
    sscanf(msg, "%d", &(handle->server_list[handle->srv_idx]->data_format));
    free(msg);

    if(gs_recv_string(sock, &msg) < 0)
      goto error_communication_failed;
    handle->problem_desc = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
    if(gs_decode_problem(msg, handle->problem_desc) < 0) {
      grpc_minor_errno = GRPC_PROBLEM_DECODE;
      goto error_client_internal_error;
    }
    FREE(msg);
  }

  handle->num_calls++;
#ifdef GS_SMART_GRIDSOLVE
  if((nb_mapped_tasks_executed<total_nb_mapped_tasks) &
    (smart_phase==GS_SMART_STANDARD_EXEC)){
    /*
     * If previous execution of this mapped tasks 
     * failed then set the remote comm variable to 0
     */
    handle->problem_desc->has_smart_arg_comm=0;

  }
#endif

  if(blocking) {
    if(gs_handle_blocking_call(handle, argptr, argstack, sock, my_dsig) < 0)
    {
      if(gs_notify_agent_of_failure(handle, request_id) < 0)
        ERRPRINTF("Warning: failed to notify agent of server failure.\n");
      FREE(request_id);
      goto error_communication_failed;
    }
#ifdef GS_SMART_GRIDSOLVE
   /*
    * after this blocking task is executed, check if there are still more 
    * mapped tasks to execute. if so then increment the number of mapped tasks executed
    */    
    if(nb_mapped_tasks_executed<total_nb_mapped_tasks){
      nb_mapped_tasks_executed++;
    }
    /*
     * if the last mapped task has just been executed
     * then reset counters
     */ 
    else{
      //free mapping and maybe task graph
      nb_mapped_tasks_executed=0;
      total_nb_mapped_tasks=0;
    }
#endif


    FREE(request_id);
  }
  else {
    if(gs_handle_nonblocking_call(handle, sessionId, argptr, argstack, sock,
          my_dsig, request_id) < 0)
    {
      if(gs_notify_agent_of_failure(handle, request_id) < 0)
        ERRPRINTF("Warning: failed to notify agent of server failure.\n");
      goto error_communication_failed;
    }

#ifdef GS_SMART_GRIDSOLVE
   /*
    * after this blocking task is executed, check if there are still more 
    * mapped tasks to execute. if so then increment the number of mapped tasks executed
    */    
    if(nb_mapped_tasks_executed<total_nb_mapped_tasks){
      nb_mapped_tasks_executed++;
    }
    /*
     * if the last mapped task has just been executed
     * then reset counters
     */ 
    else{
      //free mapping and maybe task graph
      nb_mapped_tasks_executed=0;
      total_nb_mapped_tasks=0;
    }
#endif
    FREE(msg);
    GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }

  FREE(msg)
  proxy_close(sock);
  return GRPC_NO_ERROR;


error_communication_failed:
#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase!=GS_SMART_STANDARD_EXEC){
    smart_phase=GS_SMART_EXEC_TASK_FAIL;
    if(sock != INVALID_SOCKET){
      proxy_close(sock);
    }
    FREE(msg);

  printf("SMART: Server %s has failed during execution .\n", srv->hostname);
    /*
     * SmartGridSolve fault tolerance
     * Failed to communicate with servers (inputs, outputs, tags etc.)
     * Sending failed server to agent to be removed from pm
     */
    
     if((sock = gs_connect_to_agent()) == INVALID_SOCKET)
       GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_AGENT_NOT_SET);
  
     if((gs_send_tag(sock, GS_SMART_FAULT_UPDATE_PM) < 0) ||
        (gs_send_string(sock, VERSION) < 0) ||
        (gs_recv_tag(sock, &tag) < 0))
          goto error_communication_failed;
        
     if(tag != GS_PROT_OK) {
       if(tag == GS_PROT_VERSION_MISMATCH) {
         GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_VERSION_MISMATCH);
       } else {
        GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NO_MINOR_ERROR);
      }
    }


    char *srv_str = NULL;
    if((gs_encode_server(&srv_str, srv) < 0) ||
       (gs_send_string(sock, srv_str) < 0)) {
      FREE(srv);
      DBGPRINTF("Failed to send server list \n");
      return -1;
    }


    
  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;

  printf("SMART: Server %s has been removed from network graph .\n", srv->hostname);
  printf("SMART: Remapping of the group of tasks will now be implemented .\n");
    
FREE(srv_str);
    return GRPC_NO_ERROR;

  }
  else{
    if(sock != INVALID_SOCKET){
      proxy_close(sock);
    }
    FREE(msg);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, grpc_minor_errno);
  }
#else
  if(sock != INVALID_SOCKET){
    proxy_close(sock);
  }
  FREE(msg);
  GRPC_RETURN(GRPC_COMMUNICATION_FAILED, grpc_minor_errno);
#endif

error_client_internal_error:
  if(sock != INVALID_SOCKET)
    proxy_close(sock);
  FREE(msg);
  GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static grpc_error_t gs_call_common_ft ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
gs_va_list *  argptr,
void **  argstack,
int  blocking 
)

This is common code for all the grpc_call_*_ft() functions. The retry on failure feature is implemented here.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request (only for non-blocking requests)
argptr -- va_list of the arguments for this call. one of argptr or argstack should be non-NULL but not both.
argstack -- array of pointers to the args for this call. one of argptr or argstack should be non-NULL but not both.
blocking -- if TRUE, this function will not return until the remote procedure has completed and all results are retrieved. if FALSE, this function returns after the input arguments have been sent to the remote server.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4578 of file gsgrpc.c.

{
  int c;
  GRPC_FAIL_IF_NOT_INITIALIZED(GRPC_NOT_INITIALIZED);

  for(c = 0; c < handle->num_servers; c++) {
    grpc_error_t rv;
#ifdef GS_SMART_GRIDSOLVE
    /*
     * If currently executing a mapped group of tasks 
     * a task fails on its first server, then set
     * standard exec phase so that the execution
     * proceeds using the standard gridsolve protocol.
     */ 
    if((c>0) && (nb_mapped_tasks_executed<total_nb_mapped_tasks)){
      smart_phase=GS_SMART_STANDARD_EXEC;
    }
#endif
    rv = gs_call_common(handle, sessionId, argptr, argstack, blocking);

    if(rv == GRPC_NO_ERROR)
      GRPC_RETURN(rv, GRPC_NO_MINOR_ERROR);

    if(handle->num_servers == 0)
      break;
    handle->srv_idx = (handle->srv_idx + 1) % handle->num_servers;
  }
  handle->srv_idx = 0;
  GRPC_RETURN(GRPC_SERVER_NOT_FOUND, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SOCKET gs_connect_to_agent (  ) 

Opens socket connection to the agent. Do DNS query the first time and cache the value for a while.

Returns:
socket descriptor on success, INVALID_SOCKET on failure.

Definition at line 294 of file gsgrpc.c.

{
  char agent_cid[CID_LEN];
  struct timeval cur;

  /* all ones will match any component ID */
  memset(agent_cid, 0xFF, CID_LEN);

  gettimeofday(&cur, NULL);

  /* check if the cached entry has expired */

  if(agent_resolved) {
    if(cur.tv_sec - agent_resolved->creation_time.tv_sec > AGENT_IP_EXPIRATION) {
      free(agent_resolved->hostname);
      free(agent_resolved);
      agent_resolved = NULL;
    }
  }

  if(!agent_resolved) {
    struct hostent *hp;
    char *tmp;

    agent_resolved = (agent_host_info_t *) malloc(sizeof(agent_host_info_t));

    if(!agent_resolved) {
      grpc_errno = GRPC_OTHER_ERROR_CODE;
      grpc_minor_errno = GRPC_OUT_OF_MEMORY;
      return INVALID_SOCKET;
    }

    tmp = getenv("GRIDSOLVE_AGENT");

    agent_resolved->hostname = tmp ? strdup(tmp) : NULL;

    if(!agent_resolved->hostname) {
      grpc_errno = GRPC_OTHER_ERROR_CODE;
      grpc_minor_errno = GRPC_AGENT_NOT_SET;
      return INVALID_SOCKET;
    }

    agent_resolved->port =
        getenv_int("GRIDSOLVE_AGENT_PORT", GRIDSOLVE_AGENT_PORT_DEFAULT);

    if((hp = gethostbyname(agent_resolved->hostname)) == NULL) {
      ERRPRINTF("Could not resolve host name '%s'\n", agent_resolved->hostname);
      perror("gethostbyname()");
      grpc_errno = GRPC_RPC_REFUSED;
      grpc_minor_errno = GRPC_AGENT_NOT_SET;
      return INVALID_SOCKET;
    }

    memcpy((void *) &(agent_resolved->ipaddr), hp->h_addr_list[0], sizeof(ipaddr_t));

    agent_resolved->creation_time = cur;
  }

  return gs_connect_to_host(agent_cid, agent_resolved->ipaddr, agent_resolved->port, 0, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_free_handle_server_list ( grpc_function_handle_t *  handle  ) 

Frees the list of servers in a function handle.

Parameters:
handle -- the handle whose server list should be freed
Returns:
0 on success, -1 on failure.

Definition at line 4999 of file gsgrpc.c.

{
  int i;

  if(!handle)
    return -1;

  if(handle->server_list) {
    /*
     * Remove/destroy any old server mapping memory/data-structures 
     */
    for(i = 0; i < handle->num_servers; i++)
      gs_server_free(handle->server_list[i]);
    free(handle->server_list);
    handle->srv_idx = 0;
    handle->num_servers = 0;
    handle->server_list = NULL;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_get_server_mapping ( char *  func_name,
grpc_function_handle_t *  handle,
gs_va_list *  args,
void **  argstack,
int  my_dsig,
int  lang,
int  major 
)

Contacts the agent (resource broker) and gets a list of servers that can execute the given function.

Parameters:
func_name -- The name of the function that the returned function handle will represent.
handle -- A pointer to a function handle structure (allocated by the user). On return, this structure will contain the relevant information needed for GridRPC to make remote procedure calls.
args -- va_list of the arguments to be used for this procedure call. This argument is optional and is used for improved scheduling. If not used, it should be NULL. One of args or argstack should be specified, but not both.
argstack -- array of arguments to be used for this procedure call. This argument is optional and is used for improved scheduling. If not used, it should be NULL. One of args or argstack should be specified, but not both.
my_dsig -- the data signature of the client machine.
lang -- the client language. should be one of: GS_CALL_FROM_C GS_CALL_FROM_FORTRAN
major -- the matrix storage format. should be 'r' or 'c'.
Returns:
0 on success, -1 on failure.

if(handle->criteria == NULL) msg = strdup("null"); else msg = strdup(handle->criteria);

if(!msg) { grpc_minor_errno = GRPC_OUT_OF_MEMORY; goto error_client_internal_error; }

if(gs_send_string(sock, msg) < 0) goto error_communication_failed; FREE(msg); msg = NULL;

Definition at line 2568 of file gsgrpc.c.

{
  char *msg = NULL;
  int tag, i, argsize;
  SOCKET sock;
  int scalar_args_to_be_transferred = 0;
  int problem_desc_to_be_transferred = 0;
  handle->agent_taskid = -1;

  grpc_minor_errno = GRPC_NO_MINOR_ERROR;

  if(!func_name) {
    grpc_errno = GRPC_OTHER_ERROR_CODE;
    grpc_minor_errno = GRPC_NULL_FUNCTION_NAME;
    return -1;
  }

  if((sock = gs_connect_to_agent()) == INVALID_SOCKET) {
    grpc_errno = GRPC_RPC_REFUSED;
    grpc_minor_errno = GRPC_AGENT_NOT_SET;
    return -1;
  }

  if((gs_send_tag(sock, GS_PROT_PROBLEM_SUBMIT) < 0) ||
     (gs_send_string(sock, VERSION) < 0))
    goto error_communication_failed;

  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;
  
  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;

    grpc_errno = GRPC_OTHER_ERROR_CODE;
    return -1;
  }

  if(gs_encode_problem_submit_request(&msg, func_name, my_dsig, handle->criteria) < 0) {
    grpc_minor_errno = GRPC_SUBMIT_REQ_ENCODE;
    goto error_client_internal_error;
  }

  if(gs_send_string(sock, msg) < 0)
    goto error_communication_failed;
  FREE(msg);
  msg = NULL;

  /*
   * Receive the problem description if necessary 
   */
  if(handle->problem_desc != NULL) {
    problem_desc_to_be_transferred = 0;
    if(gs_send_int(sock, problem_desc_to_be_transferred) < 0)
      goto error_communication_failed;
  }
  else {
    problem_desc_to_be_transferred = 1;
    if(gs_send_int(sock, problem_desc_to_be_transferred) < 0)
      goto error_communication_failed;
    if(gs_recv_string(sock, &msg) < 0)
      goto error_communication_failed;
    if((handle->problem_desc =
        (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t))) == NULL) {
      grpc_minor_errno = GRPC_OUT_OF_MEMORY;
      goto error_client_internal_error;
    }
    if(gs_decode_problem(msg, handle->problem_desc) < 0) {
      grpc_minor_errno = GRPC_PROBLEM_DECODE;
      goto error_communication_failed;
    }
    FREE(msg);
  }

  if(!strcmp(handle->problem_desc->description, GS_UNKNOWN_PROB)) {
    DBGPRINTF("Client Error: problem not found\n");
    if(sock != INVALID_SOCKET)
      proxy_close(sock);
    gs_free_problem(handle->problem_desc);
    handle->problem_desc = NULL;
    grpc_errno = GRPC_FUNCTION_NOT_FOUND;
    return -1;
  }

  /*
   * If one of args,argstack,my_dsig is passed in, then we need to send input 
   * scalars so that the agent can do agent side scheduling 
   */
  if(args || argstack || my_dsig != -1) {
    gs_va_list *vlptr, tmp_va_list;

    scalar_args_to_be_transferred = 1;

    if(gs_send_int(sock, scalar_args_to_be_transferred) < 0)
      goto error_communication_failed;

    /*
     * make a copy of the va_list if necessary before the call to
     * gs_send_input_scalar_args() since it seems to get clobbered and causes 
     * problems to reuse it for the actual submission. 
     */

    if(args) {
      va_copy(tmp_va_list.args, args->args);
      vlptr = &tmp_va_list;
    }
    else
      vlptr = NULL;

    if(gs_send_input_scalar_args(vlptr, argstack, sock, handle->problem_desc,
                                 my_dsig, grpc_client_lang,
                                 grpc_client_major) < 0)
      goto error_communication_failed;
  }
  else {
    scalar_args_to_be_transferred = 0;
    if(gs_send_int(sock, scalar_args_to_be_transferred) < 0)
      goto error_communication_failed;
  }

  /*
   * Receive the agent's task id.
   */
  if(gs_recv_int(sock, &(handle->agent_taskid)) < 0)
    goto error_communication_failed;

  /* agent task id useless if not transferring args */

  if(!scalar_args_to_be_transferred)
    handle->agent_taskid = -1;

  /*
   * Receive number of servers 
   */
  if(gs_recv_int(sock, &(handle->num_servers)) < 0)
    goto error_communication_failed;

  /*
   * If no servers return error 
   */
  if(handle->num_servers <= 0)
    goto error_server_not_found;

  if(handle->server_list)
    gs_free_handle_server_list(handle);

  handle->server_list = (gs_server_t **)
      CALLOC(handle->num_servers, sizeof(gs_server_t *));
  if(!handle->server_list) {
    grpc_minor_errno = GRPC_OUT_OF_MEMORY;
    goto error_client_internal_error;
  }

  for(i = 0; i < handle->num_servers; i++) {
    handle->server_list[i] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
    if(gs_recv_string(sock, &msg) < 0)
      goto error_communication_failed;
    if(gs_decode_server(msg, handle->server_list[i]) < 0) {
      grpc_minor_errno = GRPC_SERVER_DECODE;
      goto error_client_internal_error;
    }

    FREE(msg);
  }

#ifdef GS_PROFILING
  if(grpc_profile_next)
    grpc_profile_next->measure_comm = 0.0;
#endif

  if(grpc_measure_comm) {
    argsize = gs_get_total_arg_size(handle);

    if(argsize > GS_ARG_SIZE_THRESH)
      if(gs_measure_network_perf(handle) == 0)
        gs_sort_servers_on_comp_plus_comm(handle, argsize);
  }

  if(handle->num_servers > 0) {
    if(gs_recv_string(sock, &msg) < 0)
      goto error_communication_failed;

    if(handle->problem_desc)
      gs_free_problem(handle->problem_desc);

    handle->problem_desc = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
    if(!handle->problem_desc) {
      grpc_minor_errno = GRPC_OUT_OF_MEMORY;
      goto error_client_internal_error;
    }
    if(gs_decode_problem(msg, handle->problem_desc) < 0) {
      grpc_minor_errno = GRPC_PROBLEM_DECODE;
      goto error_client_internal_error;
    }
    FREE(msg);
  }

  proxy_close(sock);

  handle->srv_idx = 0;

  handle->func_name = strdup(func_name);

  DBGPRINTF("Got %d servers from agent for problem %s\n",
            handle->num_servers, func_name);

  return 0;

error_communication_failed:
  DBGPRINTF("Client Error: Communication failed\n");
  FREE(msg);
  if(sock != INVALID_SOCKET)
    proxy_close(sock);
  grpc_errno = GRPC_COMMUNICATION_FAILED;
  return -1;

error_client_internal_error:
  DBGPRINTF("Client Error: Client internal error\n");
  FREE(msg);
  if(sock != INVALID_SOCKET)
    proxy_close(sock);
  grpc_errno = GRPC_OTHER_ERROR_CODE;
  return -1;

error_server_not_found:
  DBGPRINTF("Client Error: Server not found\n");
  FREE(msg);
  if(sock != INVALID_SOCKET)
    proxy_close(sock);
  grpc_errno = GRPC_SERVER_NOT_FOUND;
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int gs_get_total_arg_size ( grpc_function_handle_t *  handle  ) 

Gets a rough idea of the number of bytes that will be transferred to submit this problem. It's not exact due to GS_VAROUT, etc.

Parameters:
handle -- the handle for the function call
Returns:
the number of bytes that will be transferred or -1 on error.

Definition at line 2502 of file gsgrpc.c.

{
  int my_dsig, total_bytes;
  gs_argument_t *argptr;

  my_dsig = pvmgetdsig();
  total_bytes = 0;
    
  for(argptr=handle->problem_desc->arglist;argptr;argptr=argptr->next) {
    int elsize = 0;

    /* For input/output args, double the elsize since it will be
     * a round trip.  Workspace args are not transferred, so use zero
     * for them.  For variable length output, we have no idea what the
     * size will be, so just choose some small value.
     */

    switch(argptr->inout) {
      case GS_INOUT:
        elsize = 2 * argptr->rows * argptr->cols * 
                 gs_get_element_size(argptr->datatype, my_dsig);
        break;
      case GS_WORKSPACE:
        elsize = 0;
        break;
      case GS_VAROUT:
        elsize = 8;
        break;
      default:
        elsize = argptr->rows * argptr->cols * 
                 gs_get_element_size(argptr->datatype, my_dsig);
    }

    total_bytes += elsize;
  }

  return total_bytes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_handle_blocking_call ( grpc_function_handle_t *  handle,
gs_va_list *  argptr,
void **  argstack,
SOCKET  sock,
int  my_dsig 
) [static]

Handles sending the data to the server and waiting for the results to come back (for blocking requests only).

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
argptr -- va_list of the arguments for this call. one of argptr or argstack should be non-NULL but not both.
argstack -- array of pointers to the args for this call. one of argptr or argstack should be non-NULL but not both.
sock -- the socket descriptor for the connection to the server
my_dsig -- data signature of this machine
Returns:
0 on success, -1 on failure

Definition at line 3045 of file gsgrpc.c.

{
  int status_tag;



#ifdef GS_SMART_GRIDSOLVE

  /*
   * Sending has_smart_arg_comm variable to the assigned server.
   * This variable specifies whether the remote task requires 
   * remote communication. This variable will be set to 1,
   * if the inputs are stored remotely or if the output arguments
   * should be sent remotely or cached locally.
   * 
   */ 

  if(gs_send_int(sock, handle->problem_desc->has_smart_arg_comm)<0){
    ERRPRINTF("SMART: Error sending has smart comm\n");
    return -1;
  }
 
 
  if(handle->problem_desc->has_smart_arg_comm){
   /*
    * If the remote task requires remote communication, then the mapping
    * information is sent to the server. This mapping info outlines
    * which inputs should be received from client, server file or server
    * memory. It also outlines which should be sent to client, stored
    * locally or sent remotely to another or 
    * multiple servers.
    */  
    if(gs_smart_send_map_info(sock, handle->problem_desc)<0){
      ERRPRINTF("SMART : Error sending mapping info\n");
      return -1;
    }
   /*
    * The client sends only the input arguments to the server
    * which have been outlined in the mapping solution.
    */  
    if(gs_smart_send_input_args(argptr, argstack, sock, handle->problem_desc,
                        my_dsig, grpc_client_lang, grpc_client_major) < 0)
      return -1;



     int pid; 
     pid=fork();
      if(pid==-1){
        ERRPRINTF("SMART: Out of memory could not fork\n");
        return -1;
      }

      if(pid==0){
        /*
         * Send input arguments from client to other servers as outlined by 
         * mapping solution
         */ 
        if(gs_smart_send_input_args_remotely(sock, handle->problem_desc, my_dsig)<0){
          ERRPRINTF("SMART : Error sending smart sending arguments\n");
          return -1;
        }
        _exit(0);
      }

 
  }
  else{
    if(gs_send_input_args(argptr, argstack, sock, handle->problem_desc,
                        my_dsig, grpc_client_lang, grpc_client_major) < 0)
      return -1;
  }
#else
  if(gs_send_input_args(argptr, argstack, sock, handle->problem_desc,
                        my_dsig, grpc_client_lang, grpc_client_major) < 0)
    return -1;
#endif



#ifdef GS_PROFILING
  if(grpc_profile_next) {
    GRPC_TIMER_STOP(grpc_profile_next);
    grpc_profile_next->send_input = GRPC_TIMER_ELAPSED(grpc_profile_next);
    GRPC_TIMER_START(grpc_profile_next);
  }
#endif

  if(gs_wait_for_output(sock) < 0) {
    ERRPRINTF("error waiting for output to be ready\n");
    return -1;
  }

  if(gs_recv_tag(sock, &status_tag) < 0)
    return -1;

  if(status_tag != GS_PROT_OK) {
    ERRPRINTF("Service failed: %s\n", gs_service_error[status_tag]);
    return -1;
  }


#ifdef GS_SMART_GRIDSOLVE
  if(handle->problem_desc->has_smart_arg_comm==1){
   /*
    * The client receives only the output arguments from the server
    * which have been outlined in the mapping solution.
    */  
    if(gs_smart_recv_output_args(sock, handle->problem_desc, handle->server_list[handle->srv_idx]->data_format, 
                                 my_dsig) < 0){
      ERRPRINTF("SMART: Error trying to receive output args\n");
      return -1;
    }
  }
  else{
    if(gs_recv_output_args(sock, handle->problem_desc,
                         handle->server_list[handle->srv_idx]->data_format,
                         my_dsig) < 0)
      return -1;
  }
#else
  if(gs_recv_output_args(sock, handle->problem_desc,
                         handle->server_list[handle->srv_idx]->data_format,
                         my_dsig) < 0)
    return -1;
#endif


#ifdef GS_PROFILING
  if(grpc_profile_next) {
    GRPC_TIMER_STOP(grpc_profile_next);
    grpc_profile_next->recv_output = GRPC_TIMER_ELAPSED(grpc_profile_next);
  }
#endif

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_handle_nonblocking_call ( grpc_function_handle_t *  handle,
grpc_sessionid_t *  sessionId,
gs_va_list *  argptr,
void **  argstack,
SOCKET  sock,
int  my_dsig,
char *  request_id 
) [static]

Handles sending the data to the server and setting up the appropriate data structures to keep track of this request. This is for non-blocking requests only.

Parameters:
handle -- the handle representing the function to be called, the server to use, proxy, etc.
sessionId -- upon return, is set to the session ID for the request
argptr -- va_list of the arguments for this call. one of argptr or argstack should be non-NULL but not both.
argstack -- array of pointers to the args for this call. one of argptr or argstack should be non-NULL but not both.
sock -- the socket descriptor for the connection to the server
my_dsig -- data signature of this machine
request_id -- the request ID generated by the server
Returns:
0 on success, -1 on failure

Definition at line 3205 of file gsgrpc.c.

{
  int idx = get_next_request_id();
  grpc_request_t *new_req;
  int retval = 0;


#ifdef GS_SMART_GRIDSOLVE
  /*
   * Sending has_smart_arg_comm variable to the assigned server.
   * This variable specifies whether the remote task requires 
   * remote communication. This variable will be set to 1,
   * if the inputs are stored remotely or if the output arguments
   * should be sent remotely or cached locally.
   * 
   */ 
  if(gs_send_int(sock, handle->problem_desc->has_smart_arg_comm)<0){
    ERRPRINTF("SMART: Error sending has smart comm\n");
    return -1;
  }


  if(handle->problem_desc->has_smart_arg_comm){
   /*
    * If the remote task requires remote communication, then the mapping
    * information is sent to the server. This mapping info outlines
    * which inputs should be received from client, server file or server
    * memory. It also outlines which should be sent to client, stored
    * locally or sent remotely to another or 
    * multiple servers.
    */  
    if(gs_smart_send_map_info(sock, handle->problem_desc)<0){
      ERRPRINTF("SMART : Error sending mapping info\n");
      return -1;
    }
  }  

#endif




  /*
   * before forking, call gs_send_input_scalar_args() so that the arg sizes
   * will be computed and stored in this problem struct.  it's better to do
   * this prior to forking because we'd otherwise need to communicate the
   * sizes back to the parent process. 
   */

  if(gs_send_input_scalar_args(argptr, argstack, sock, handle->problem_desc,
                               my_dsig, grpc_client_lang,
                               grpc_client_major) < 0)
    return -1;

  new_req = (grpc_request_t *) malloc(sizeof(grpc_request_t));
  if(!new_req || (idx < 0))
    return -1;

  new_req->request_id = request_id;
  new_req->handle = handle;

  /*
   * we need to dup the problem in case the user submits subsequent requests
   * with different arguments. 
   */
  new_req->problem = (gs_problem_t *) malloc(sizeof(gs_problem_t));
  if(!new_req->problem)
    return -1;

  if(gs_dup_problem(new_req->problem, handle->problem_desc) < 0)
    return -1;

  grpc_outstanding_requests[idx] = new_req;
  grpc_profile_info[idx] = grpc_profile_next;


/* NOTE: On Win32 we do not fork to send the arguments, we send them in this process */
/* TODO: ayk, should replace WIN32 with ifndef HAVE_FORK */
#if defined (WIN32) || defined (WINNT)
  grpc_outstanding_requests[idx]->s_pid = 0;
  retval = gs_send_input_nonscalar_args(sock, handle->problem_desc, my_dsig);
  proxy_close(sock);
#else
  grpc_outstanding_requests[idx]->s_pid = fork();

  switch (grpc_outstanding_requests[idx]->s_pid) {
    case -1:
      ERRPRINTF("Failed to fork process to send input data\n");
      grpc_request_destruct_free_clear(idx);
      return -1;

    case 0:                    /* child */

#ifdef GS_SMART_GRIDSOLVE
      if(handle->problem_desc->has_smart_arg_comm==1){
       /*
        * The client sends only the input arguments to the server 
        * which have been outlined in the mapping solution.
        */  
        if(gs_smart_send_input_nonscalar_args(sock, handle->problem_desc, my_dsig) < 0)
          _exit(-1);
     

        int pid; 
        pid=fork();
        if(pid==-1){
          ERRPRINTF("SMART: Out of memory could not fork\n");
          return -1;
        }

        if(pid==0){
         /*
          * Send input arguments from client to other servers as outlined by mapping solution
          */ 
          if(gs_smart_send_input_args_remotely(sock ,handle->problem_desc, my_dsig)<0){
            ERRPRINTF("SMART : Error sending smart sending arguments\n");
            return -1;
          }
          _exit(0);
        }

      }
      else{
        if(gs_send_input_nonscalar_args(sock, handle->problem_desc, my_dsig) < 0)
          _exit(-1);
      
      }
#else

      if(gs_send_input_nonscalar_args(sock, handle->problem_desc, my_dsig) < 0)
        _exit(-1);
#endif
      proxy_close(sock);
      _exit(0);

    default:                   /* parent */
      proxy_close(sock);
  }
#endif

  *sessionId = idx;
  return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int gs_measure_network_perf ( grpc_function_handle_t *  handle  ) 

Performs quick network measurement to some of the servers in the list.

Parameters:
handle -- the function handle for this request
Returns:
0 on success, -1 on failure

Definition at line 2303 of file gsgrpc.c.

{
  int i, len, ns, nping;
  char *msg;
  grpc_profile_t profile_tmp;

  memset(&profile_tmp, 0, sizeof(grpc_profile_t));

#ifdef GS_PROFILING
  GRPC_TIMER_START(&profile_tmp);
#endif

  ns = MIN(handle->num_servers, grpc_measure_comm_num_servers);
  len = 32 * 1024;

  msg = (char *)malloc(len);

  if(!msg)
    return -1;

  nping = 0;

  for(i=0;i<handle->num_servers;i++) {
    char srv_cid[2*CID_LEN+1];
    grpc_cache_entry_t *ent;
    double elapsed_time;

    proxy_cid_to_str(srv_cid, handle->server_list[i]->componentid);

    if(grpc_comm_cache) {
      ent = (grpc_cache_entry_t *) icl_hash_find(grpc_comm_cache, srv_cid);

      /* check if this entry is out of date */
      if(ent) {
        struct timeval ctv;

        gettimeofday(&ctv, NULL);

        if(ctv.tv_sec - ent->tv.tv_sec > grpc_measure_comm_cache_ttl)
          ent = NULL;
      }
    }
    else
      ent = NULL;

    if(ent) {
      handle->server_list[i]->comm_bw = ent->comm_bw; 
    }
    else {
      if(gs_do_ping(handle->server_list[i], msg, len, &elapsed_time) < 0) {
        handle->server_list[i]->comm_bw = 0.0;
      }
      else {
        handle->server_list[i]->comm_bw = len / elapsed_time;

        if(grpc_comm_cache) {
          ent = (grpc_cache_entry_t *)malloc(sizeof(grpc_cache_entry_t));

          if(ent) {
            char *cid_dup;

            cid_dup = strdup(srv_cid);

            if(!cid_dup) {
              free(ent);
            }
            else {
              void *old_ent;

              gettimeofday(&(ent->tv), NULL);
              ent->comm_bw = handle->server_list[i]->comm_bw;

              icl_hash_update_insert(grpc_comm_cache, cid_dup, ent, &old_ent);
            }
          }
        }
      }

      nping++;
    }
  
    if(nping == ns)
      break;
  }

  free(msg);

#ifdef GS_PROFILING
  GRPC_TIMER_STOP(&profile_tmp);
  if(grpc_profile_next)
    grpc_profile_next->measure_comm = GRPC_TIMER_ELAPSED(&profile_tmp);
#endif

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_notify_agent_of_cancel ( grpc_function_handle_t *  handle,
char *  reqid 
)

Notify the agent that the client cancelled the request.

Parameters:
handle -- function handle from the cancelled request
reqid -- request ID of the cancelled request
Returns:
0 on success, -1 on failure.

Definition at line 3361 of file gsgrpc.c.

{
  char *msg, srv_cid[2*CID_LEN+1];
  SOCKET sock;
  int tag, agent_taskid;

#if !defined (WIN32) && !defined (WINNT)
  pid_t childpid;
  childpid = fork();

  if(childpid < 0) {
    ERRPRINTF("Failed to fork.\n");
    return -1;
  }

  if(childpid > 0)
    return 0;
#endif

  if(handle->num_calls > 1)
    agent_taskid = -1;
  else
    agent_taskid = handle->agent_taskid;

  /* all code after here is executed in the child process */

  if((sock = gs_connect_to_agent()) == INVALID_SOCKET) {
    grpc_errno = GRPC_RPC_REFUSED;
    _exit(-1);
  }

  proxy_cid_to_str(srv_cid, handle->server_list[handle->srv_idx]->componentid);

  if((gs_send_tag(sock, GS_PROT_NOTIFY_CANCEL) < 0) ||
     (gs_send_string(sock, VERSION) < 0)) {
    ERRPRINTF("failed to send tag\n");
    close_socket(sock);
    _exit(-1);
  }

  if(gs_recv_tag(sock, &tag) < 0) {
    ERRPRINTF("Error communicating with agent.\n");
    close_socket(sock);
    _exit(-1);
  }

  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      ERRPRINTF("Error: Agent is an incompatible version\n");
    else
      ERRPRINTF("Error: Agent refused with code %d\n", tag);
    close_socket(sock);
    _exit(-1);
  }

  if(gs_encode_cancel_notification(&msg, srv_cid, reqid, agent_taskid) < 0)
  {
    ERRPRINTF("Failed to encode message\n");
    close_socket(sock);
    _exit(-1);
  }

  if(gs_send_string(sock, msg) < 0) {
    ERRPRINTF("failed to send tag\n");
    free(msg);
    close_socket(sock);
    _exit(-1);
  }

  free(msg);
#if !defined (WIN32) && !defined (WINNT)
  close_socket(sock);
  _exit(0);
#endif
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_notify_agent_of_failure ( grpc_function_handle_t *  handle,
char *  reqid 
) [static]

Notify the agent that the server failed to handle the request.

Parameters:
handle -- function handle from the failed request
reqid -- request ID of the failed request
Returns:
0 on success, -1 on failure.

Definition at line 3448 of file gsgrpc.c.

{
  char *msg, srv_cid[2*CID_LEN+1];
  SOCKET sock;
  int tag, agent_taskid;

#if !defined (WIN32) && !defined (WINNT)
  pid_t childpid;
  childpid = fork();

  if(childpid < 0) {
    ERRPRINTF("Failed to fork.\n");
    return -1;
  }

  if(childpid > 0)
    return 0;
#endif /* WIN32 */

  if(handle->num_calls > 1)
    agent_taskid = -1;
  else
    agent_taskid = handle->agent_taskid;

  /* all code after here is executed in the child process */

  if((sock = gs_connect_to_agent()) == INVALID_SOCKET) {
    grpc_errno = GRPC_RPC_REFUSED;
    _exit(-1);
  }

  proxy_cid_to_str(srv_cid, handle->server_list[handle->srv_idx]->componentid);

  if((gs_send_tag(sock, GS_PROT_NOTIFY_FAILURE) < 0) ||
     (gs_send_string(sock, VERSION) < 0)) {
    ERRPRINTF("failed to send tag\n");
    close_socket(sock);
    _exit(-1);
  }

  if(gs_recv_tag(sock, &tag) < 0) {
    ERRPRINTF("Error communicating with agent.\n");
    close_socket(sock);
    _exit(-1);
  }

  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      ERRPRINTF("Error: Agent is an incompatible version\n");
    else
      ERRPRINTF("Error: Agent refused with code %d\n", tag);
    close_socket(sock);
    _exit(-1);
  }

  if(gs_encode_failure_notification(&msg, srv_cid, reqid, agent_taskid) < 0)
  {
    ERRPRINTF("Failed to encode message\n");
    close_socket(sock);
    _exit(-1);
  }

  if(gs_send_string(sock, msg) < 0) {
    ERRPRINTF("failed to send tag\n");
    free(msg);
    close_socket(sock);
    _exit(-1);
  }

  free(msg);
#if !defined (WIN32) && !defined (WINNT)
  close(sock);
  _exit(0);
#endif /* WIN32 */
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_parse_host_info ( char *  host_str,
ipaddr_t *  ip,
in_port_t *  port,
ipaddr_t *  proxyip,
in_port_t *  proxyport,
char *  cid 
)

Parses an "assigned server" string specified by the user. The format of this string should be: serverhost_PoD_serverport_PrD_proxyhost_PoD_proxyport where _PoD_ represents the port delimiter and _PrD_ represents the proxy delimiter. Currently the actual format is: serverhost/serverportproxyhost/proxyport [if the delimiters are changed this routine does not need to be changed]

Parameters:
host_str -- the host/portproxy/pport string specified by the user.
ip -- on return, the server's IP address is stored in this variable
port -- on return, the server's port number is stored in this variable
proxyip -- on return, the proxy's IP address is stored in this variable
proxyport -- on return, the proxy's port number is stored in this variable
cid -- on return, the component ID (if it was specified as part of the string) is stored in this variable
Returns:

Definition at line 2906 of file gsgrpc.c.

{
  char *tok, *component_tok = NULL, *proxy_tok = NULL, delim[2];

  delim[0] = GS_PROXY_DELIM;
  delim[1] = '\0';

  /*
   * first get the part before the proxy delimiter.  this will be the server
   * host name and port. 
   */

  tok = strtok(host_str, delim);
  if(!tok)
    goto gs_parse_host_info_error;

  /*
   * copy this token for use later since strtok trashes things 
   */

  component_tok = strdup(tok);
  if(!component_tok)
    goto gs_parse_host_info_error;

  /*
   * now get the proxy part of the string 
   */
  tok = strtok(NULL, delim);
  if(!tok) {
    /*
     * no proxy specified 
     */
    proxy_tok = NULL;
    *proxyip = 0;
    *proxyport = 0;
    memset(cid, 0xFF, CID_LEN);
  }
  else {
    proxy_tok = strdup(tok);
    if(!proxy_tok)
      goto gs_parse_host_info_error;

    if(gs_parse_host_port(proxy_tok, proxyip, proxyport) < 0)
      goto gs_parse_host_info_error;
  }

  /*
   * check whether the server host name looks like a component ID 
   */

  if(component_tok[0] == '0' &&
     (component_tok[1] == 'x' || component_tok[1] == 'X')) {
    char delim[2];

    if(*proxyip == 0) {
      ERRPRINTF("If specifying a cid, proxy must be specified\n");
      goto gs_parse_host_info_error;
    }

    delim[0] = GS_PORT_DELIM;
    delim[1] = '\0';

    tok = strtok(component_tok, delim);
    if(!tok)
      goto gs_parse_host_info_error;

    proxy_str_to_cid(cid, tok);
    *ip = 0;

    tok = strtok(NULL, delim);
    if(!tok)
      goto gs_parse_host_info_error;

    *port = atoi(tok);
  }
  else {
    if(*proxyip != 0) {
      ERRPRINTF
          ("If proxy is used, component ID must be specified (not IP)\n");
      goto gs_parse_host_info_error;
    }

    memset(cid, 0xFF, CID_LEN);
    if(gs_parse_host_port(component_tok, ip, port) < 0)
      goto gs_parse_host_info_error;
  }

  if(component_tok)
    free(component_tok);
  if(proxy_tok)
    free(proxy_tok);

  return 0;

gs_parse_host_info_error:
  if(component_tok)
    free(component_tok);
  if(proxy_tok)
    free(proxy_tok);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gs_parse_host_port ( char *  str,
ipaddr_t *  ip,
in_port_t *  port 
)

Parse the host/port part of the "assigned server" string.

Parameters:
str -- the host/port string specified by the user.
ip -- on return, the server's IP address is stored in this variable
port -- on return, the server's port number is stored in this variable
Returns:
0 on success, -1 on failure.

Definition at line 2836 of file gsgrpc.c.

{
  struct hostent *hp;
  char *tok, *host_tok = NULL, *port_tok = NULL, delim[2];

  delim[0] = GS_PORT_DELIM;
  delim[1] = '\0';

  tok = strtok(str, delim);
  if(!tok)
    goto gs_parse_host_port_error;

  host_tok = strdup(tok);
  if(!host_tok)
    goto gs_parse_host_port_error;

  tok = strtok(NULL, delim);
  if(!tok)
    goto gs_parse_host_port_error;

  port_tok = strdup(tok);
  if(!port_tok)
    goto gs_parse_host_port_error;

  if((hp = gethostbyname(host_tok)) == NULL)
    goto gs_parse_host_port_error;

  memcpy((void *) ip, hp->h_addr_list[0], sizeof(*ip));

  *port = atoi(port_tok);

  if(host_tok)
    free(host_tok);
  if(port_tok)
    free(port_tok);
  return 0;

gs_parse_host_port_error:
  if(host_tok)
    free(host_tok);
  if(port_tok)
    free(port_tok);
  return -1;
}

Here is the caller graph for this function:

static int gs_req_child_waitpid ( grpc_request_t *  req,
int  options 
) [static]

Checks the status of the child process of a previous non-blocking request to see if it has completed. If options is WNOHANG, block until the child terminates.

Parameters:
req -- the request whose child we want to wait for
options -- the options specificed to waitpid (e.g. WNOHANG for non-blocking or 0 for blocking)
Returns:
the process ID of the child which exited or zero if the options specified WNOHANG and the child hasn't completed.

Definition at line 1172 of file gsgrpc.c.

{
  pid_t pid, tmp_pid;
  int stat;

  pid = waitpid(req->s_pid, &stat, options);

  switch (pid) {
    case WAIT_ABANDONED:        /* -1 */
      /*
       * if we reach here, most likely it's because the user has their own
       * signal handler catching SIGCHLD signals and they're calling waitpid
       * on the process forked by grpc, so it's gone by the time we get here. 
       * in any case, just clear the s_pid field so we won't wait on it again
       * and return normally. 
       */
      tmp_pid = req->s_pid;
      req->s_pid = -1;
      return tmp_pid;

    case WAIT_TIMEOUT:      /* 0 */
      /*
       * the child process is still sending the data 
       */
      return 0;

    default:
      /*
       * the child process has completed 
       */
      tmp_pid = req->s_pid;
      req->s_pid = -1;
      return tmp_pid;
  }
}

Here is the caller graph for this function:

static grpc_error_t gs_resubmit_common ( grpc_sessionid_t  sessionID  )  [static]

This is common code used by grpc_probe_ft() and grpc_wait_ft(). The resubmission of failed jobs is handled here.

Parameters:
sessionId -- the session ID of the previously submitted request.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_SERVER_NOT_FOUND: GRPC client cannot find any server GRPC_FUNCTION_NOT_FOUND: GRPC client cannot find the function on the default server GRPC_INVALID_FUNCTION_HANDLE: Function handle pointed to by 'handle' is not valid GRPC_RPC_REFUSED: RPC invocation refused by the server GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4873 of file gsgrpc.c.

{
  grpc_function_handle_t *handle;
  int tag;
  SOCKET sock;
  int my_dsig;
  char *msg, *request_id = NULL;
  gs_server_t *srv;

  if((sessionID < 0) || (sessionID >= MAX_GRPC_REQUESTS))
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  if(!grpc_outstanding_requests[sessionID])
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);

  handle = grpc_outstanding_requests[sessionID]->handle;

  if(!handle)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_HANDLE);
  if(!handle->func_name)
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_NULL_FUNCTION_NAME);

  srv = handle->server_list[handle->srv_idx];

  sock = gs_connect_to_host(srv->componentid, srv->ipaddress, srv->port,
                            srv->proxyip, srv->proxyport);

  if(sock < 0)
    GRPC_RETURN(GRPC_RPC_REFUSED, GRPC_SERVER_CONNECTION);

  my_dsig = pvmgetdsig();
  handle->agent_taskid = -1;

  if(gs_encode_problem_solve_request(&msg, handle->func_name, 
     grpc_user, grpc_host, grpc_domain, grpc_cid_str, my_dsig,
     handle->agent_taskid, srv->score) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, GRPC_SOLVE_REQ_ENCODE);
  }

  tag = GS_PROT_PROBLEM_SOLVE;

  if((gs_send_tag(sock, tag) < 0) ||
     (gs_send_string(sock, VERSION) < 0)) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  if(gs_recv_tag(sock, &tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;

    proxy_close(sock);
    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
  }

  tag = GS_PROT_NONBLOCKING;

  if(gs_send_tag(sock, tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  if(gs_send_string(sock, msg) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  free(msg);

  if(gs_recv_tag(sock, &tag) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  if(tag != GS_PROT_OK) {
    switch (tag) {
      case GS_SVC_ERR_EXEC:
        proxy_close(sock);
        GRPC_RETURN(GRPC_FUNCTION_NOT_FOUND, GRPC_NO_MINOR_ERROR);
      default:
        ERRPRINTF("%s\n", gs_service_error[tag]);
        proxy_close(sock);
        GRPC_RETURN(GRPC_OTHER_ERROR_CODE, tag);
        break;
    }
  }

  if(gs_recv_string(sock, &request_id) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  if(gs_send_input_args(NULL, NULL, sock, handle->problem_desc,
                        my_dsig, grpc_client_lang, grpc_client_major) < 0) {
    proxy_close(sock);
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_NO_MINOR_ERROR);
  }

  /*
   * free the old request id and assign the new one 
   */
  free(grpc_outstanding_requests[sessionID]->request_id);
  grpc_outstanding_requests[sessionID]->request_id = request_id;

  proxy_close(sock);

  GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
}

Here is the call graph for this function:

static grpc_error_t gs_resubmit_common ( int   ) 

Here is the caller graph for this function:

static int gs_server_compare_total_time ( const void *  p1,
const void *  p2 
) [static]

Comparison function for use in sorting the server list. This function is used by quicksort.

Parameters:
p1 -- A pointer to a server structure s1
p2 -- A pointer to a server structure s2
Returns:
1 if s1 total time > s2 total time -1 if s1 total time < s2 total time 0 if equal

Definition at line 2412 of file gsgrpc.c.

{
  gs_server_t *s1, *s2;
  double s1_time, s2_time;

  if(!p1 || !p2) return 0;

  s1 = *((gs_server_t **) p1);
  s2 = *((gs_server_t **) p2);

  s1_time = s1->score + s1->comm_time;
  s2_time = s2->score + s2->comm_time;

  /* if the measurements are pretty close, then we just
   * consider them equal.
   */
  if(abs(s1_time - s2_time) < grpc_measure_comm_time_thresh)
    return 0;

  if(s1_time > s2_time)
    return 1;
  if(s1_time < s2_time)
    return -1;

  return 0;
}

Here is the caller graph for this function:

int gs_smart_map_ft_X ( char *  mapper_name  ) 

Definition at line 6354 of file gsgrpc.c.

                                         {
  return gs_smart_map_two_cycles(mapper_name, "disable_remote_comm"); 
}

Here is the call graph for this function:

int gs_smart_map_two_cycles ( char *  mapper_name,
char *  comm_type 
)

Generates a mapping solution for a group of tasks.

Parameters:
mapper_name -- name of the called mapping heuristic which will generate mapping solution
Returns:
0 on success, -1 on error.

Definition at line 6064 of file gsgrpc.c.

                                                                 {

#ifdef GS_SMART_GRIDSOLVE
  /*
   * list of handles session ids and blocking array of the group of 
   * tasks to be mapped. These structures are initialised
   * when gs_smart_get_handle_list is called which gets the list of
   * handles,session ids and blocking arrays which were initialised
   * in the previous pass through the group of tasks. 
   * This is used to generate the app_pm.
   * 
   */  
  grpc_function_handle_t ** handle_list;
  int nb_tasks;
  int ** blocking_array;
  grpc_sessionid_t ** session_ids;

  /* 
   * application performance model is used by agent 
   * to generate task graph for the group of tasks.
   */
  gs_smart_app_pm * app_pm=NULL;

  /*
   * task graph and network performance model
   * used by mapping heuristic to generate
   * a mapping solution for the group of tasks.
   */
  gs_smart_tg * tg=NULL;
  gs_smart_netpm * netpm=NULL;

  call_type=GS_SMART_TWO_PASS_CALL;  
  group_type=GS_SMART_IMPLICIT_GROUP;  

  if(!mapper_name){
    ERRPRINTF("SMART : Error mapper name is NULL\n");
    smart_phase=GS_SMART_MAP_FAIL;
    return -1;
  }

  /*
   * The first time  gs_smart_map is called 
   * the GS_SMART_TASK_DISCOVERY phase is set, the 
   * mapping parameters parameters are then set. After this we enter the first pass (pass 0)
   * through the scope of the group of tasks, this is done by returning 1.
   * In this pass task discovery is performed.
   */ 
  if((current_pass==0) && (smart_phase==GS_SMART_STANDARD_EXEC)){


    /* Free the previous handle list */
    if(gs_smart_free_handle_list()<0){
      ERRPRINTF("SMART: Error freeing handle list\n");
      return -1;
    } 

    /*** First time this function is called enter here ***/
    smart_phase=GS_SMART_TASK_DISCOVERY;
    nb_mapped_tasks_executed=0;
    total_nb_mapped_tasks=0;

    /*
     *  if mapper name is left empty use default mapper
     */
    if(strcmp(mapper_name, "")==0){    
      if(gs_smart_set_mapper_type("greedy_map")<0){
        ERRPRINTF("SMART: Default mapper not found\n");
        smart_phase=GS_SMART_MAP_FAIL;
        return -1;
      }
    }
    else{
      if(gs_smart_set_mapper_type(mapper_name)<0){
        ERRPRINTF("SMART: %s mapper not found\n", mapper_name);
        smart_phase=GS_SMART_MAP_FAIL;
        return -1;
      }
    }
    if(strcmp(comm_type, "")==0){    
      set_comm_type="enable_remote_comm";
    }
    else{
      if((strcmp(comm_type,"enable_remote_comm")==0) |
         (strcmp(comm_type, "disable_remote_comm")==0) |
         (strcmp(comm_type, "no_dep")==0) |
         (strcmp(comm_type, "server_comm")==0)){
        set_comm_type=comm_type;
      }
      else{
       ERRPRINTF("SMART : Did not recognise the second parameter to GS_SMART_MAP\n");
       set_comm_type="enable_remote_comm";
      }
    }
    return 1;
  }


  /*
   * The second time  gs_smart_map is called 
   * the GS_SMART_MAPPING phase is set.
   * Once this is done the group of tasks is mapped.
   * After this is the second pass (pass 1) 
   * through the scope of the group of tasks. Therefore 1 is returned to enter second pass.
   *  On this pass through the group of tasks, each called handle is executed 
   *  according to the mapping. This phase is called the GS_SMART_EXEC_CALLED_HANDLES phase.
   */ 

  else if((current_pass==0) && (smart_phase==GS_SMART_TASK_DISCOVERY)){
    /*** Second time this function is called enter here ***/
    smart_phase=GS_SMART_MAPPING;
   /*
    * Get the stored list of handles which was initalised on the first pass through
    * the group of tasks.  These are the handles of each task in the group of tasks
    * which are to be mapped.
    */  
   if(gs_smart_get_handle_list(&handle_list,&session_ids, &blocking_array, &nb_tasks)<0){   
      ERRPRINTF("SMART: Error getting handle list\n");
       smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }
    if((!handle_list) || (!session_ids) || (!blocking_array)) return -1;

    app_pm=(gs_smart_app_pm *)calloc(1, sizeof(gs_smart_app_pm));
    if(!app_pm){
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }

    /*
     * Generate the application performance model based on the stored
     * list of handles and blocking array. 
     */ 

    if(gs_smart_generate_app_pm(handle_list, blocking_array, nb_tasks, app_pm)<0){
      ERRPRINTF("SMART: Error building application performance model\n");
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }

    tg = (gs_smart_tg *)calloc(1,sizeof(gs_smart_tg)); 
    netpm=(gs_smart_netpm *)calloc(1, sizeof(gs_smart_netpm));
 
    if( (!tg) || (!netpm)){
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }

    /*
     * Send app_pm to agent. The agent then generates the task graph
     * based on the app_pm and the information in the idl files of each
     * task which is stored on the ageny. 
     *
     * The agent also sends back the a list of servers and the
     * network performance model is generated from this list of servers
     */ 
    if(gs_smart_generate_netpm_and_task_graph(app_pm,  tg, netpm,set_comm_type)){
      ERRPRINTF("SMART: Error generating task graph\n");
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }
 
    /* 
     * THESE FUNCTIONS ARE JUST TEMPORARY FOR DEMONSTRATION OF HOW
     * SMARTGRIDSOLVE EXTENSION WORKS 
     */
/*
    if(gs_smart_net_pm_print_to_dotgraph(netpm, "smart_graphs/netpm.dot")<0){
      ERRPRINTF("SMART : Error printing network performance model dotgraph\n");
    }
   
    if(gs_smart_tg_print_to_dotgraph(tg, "smart_graphs/task_graph.dot")<0){
      ERRPRINTF("SMART : Error printing dotgraph\n ");
      return -1;
    }
    system("dot -Tjpg smart_graphs/task_graph.dot -o smart_graphs/task_graph.jpg");
    system("dot -Tjpg smart_graphs/netpm.dot -o smart_graphs/netpm.jpg");
     
*/

    if(gs_smart_get_mapper_type(&mapper_name)<0){
      ERRPRINTF("SMART: Error getting automatic mapper type\n");
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }

    /*
     * Call the mapping heuristic (mapper_name) specified by the application programmer.
     * The group of tasks is mapped based  on the task graph and network performance 
     * model.  This function generates a mapping solution 
     * (best_mg in gs_smart_mapping_solution.h) which will be used when
     * executing the group of tasks.
     */      
    if(gs_smart_map_common(mapper_name, tg, netpm, &total_nb_mapped_tasks)<0){
      ERRPRINTF("SMART: Error doing automatic mapping");
      smart_phase=GS_SMART_MAP_FAIL;
      return -1;
    }

    smart_phase=GS_SMART_EXEC_CALLED_HANDLES;
    current_pass=1;
    return 1;
  }

  /*
   * The third time  gs_smart_map is called 
   * we reset the current pass variable and set
   * the smart_phase to GS_SMART_STANDARD_EXEC so that each of the called handles
   * is executed in standard GridSolve.
   * And then we exit out of the scope of the group of tasks which is done by returning 0;
   */ 
  else if((current_pass==1) && (smart_phase==GS_SMART_EXEC_CALLED_HANDLES)){
    current_pass=0;
    smart_phase=GS_SMART_STANDARD_EXEC;

    if(app_pm){
      if(gs_smart_app_pm_free(app_pm)<0){
        ERRPRINTF("SMART : Error freeing application performance model\n");
        smart_phase=GS_SMART_MAP_FAIL;
        return -1;
      }
    }
    if(tg){
      if(gs_smart_tg_free(tg)<0){
        ERRPRINTF("SMART : Error freeing task graph\n");
        smart_phase=GS_SMART_MAP_FAIL;
        return -1;
      }
    }
     if(netpm){
      if(gs_smart_netpm_free(netpm)<0){
        ERRPRINTF("SMART : Error freeing network performance model\n");
        smart_phase=GS_SMART_MAP_FAIL;
        return -1;
      }

    }
    return 0;
  } 
return 0;

#else
 
 if(current_pass==0){
    printf("SMART: Unable to map tasks as GRIDSOLVE was not configured with the SMARTGRIDSOLVE extension\n");
    printf("SMART: The application will execute normally\n");
    current_pass++;
    return 1;
  }
  if(current_pass==1){
    current_pass=0;
    return 0;
  }
#endif
 return 0;
}

Here is the caller graph for this function:

int gs_smart_map_X ( char *  mapper_name  ) 

Definition at line 6332 of file gsgrpc.c.

                                       {

#ifdef GS_SMART_GRIDSOLVE
  if(smart_phase==GS_SMART_EXEC_TASK_FAIL){
    current_pass=0;
    smart_phase=GS_SMART_STANDARD_EXEC;
  }
#endif
  return gs_smart_map_two_cycles(mapper_name, "enable_remote_comm"); 
}

Here is the call graph for this function:

int gs_sort_servers_on_comp_plus_comm ( grpc_function_handle_t *  handle,
int  data_size 
)

Now that the communication bandwidth is computed, we can re-sort the server list. Combine the computation time estimate provided by the agent with a communication time estimate computed here (total number of bytes to be transferred / comm_bw).

Parameters:
handle -- the function handle for this request
data_size -- number of bytes to be transferred
Returns:
0 on success, -1 on failure

Definition at line 2452 of file gsgrpc.c.

{
  gs_server_t *srv;
  double avg_bw, sum;
  int i, nnzs;

  sum = avg_bw = 0.0;
  nnzs = 0;

  for(i=0;i<handle->num_servers;i++) {
    srv = handle->server_list[i];

    if(srv->comm_bw != 0.0) {
      sum += srv->comm_bw;
      nnzs++;
    }
  }

  if(nnzs > 0)
    avg_bw = sum / (double) nnzs;
 
  if(avg_bw == 0.0)
    avg_bw = 20000.0;
    
  for(i=0;i<handle->num_servers;i++) {
    srv = handle->server_list[i];

    if(srv->comm_bw == 0.0)
      srv->comm_time = data_size / avg_bw;
    else
      srv->comm_time = data_size / srv->comm_bw;
  }

  /* Sort the servers */
  qsort(handle->server_list, handle->num_servers, sizeof(gs_server_t *),
     gs_server_compare_total_time);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

grpc_error_t gs_wait_common ( grpc_request_t *  req  ) 

This is common code used by grpc_wait() and grpc_retrieve() to wait for a request to complete.

Parameters:
req -- the previously submitted request to wait for.
Returns:
GRPC_NO_ERROR on success. On error returns: GRPC_NOT_INITIALIZED: GRPC client not initialized yet GRPC_INVALID_SESSION_ID: session ID is not valid GRPC_COMMUNICATION_FAILED: Communication with the server failed somehow GRPC_SESSION_FAILED: The specified session failed GRPC_OTHER_ERROR_CODE: Internal error detected

Definition at line 4127 of file gsgrpc.c.

{
  int my_dsig;
  SOCKET sock;
  int tag;
  gs_server_t *srv;

  grpc_minor_errno = GRPC_NO_MINOR_ERROR;

  my_dsig = pvmgetdsig();

  if(!req->handle)
    GRPC_RETURN(GRPC_INVALID_SESSION_ID, GRPC_NO_MINOR_ERROR);


#ifdef GS_SMART_GRIDSOLVE
  /*
   * Count the number of output arguments that should be 
   * received from the server as outlined in the mapping 
   * solution. If there are none the function returns.
   */ 
  
  gs_argument_t *argptr;
  int nb_args_to_receive=0;
  for(argptr= req->handle->problem_desc->arglist;argptr!=NULL;argptr=argptr->next) {
    if(argptr->objecttype!=GS_SCALAR){
      if( ( argptr->inout==GS_INOUT ) || ( argptr->inout==GS_OUT ) ) {
        if(argptr->output_arg_sent_remotely==0) nb_args_to_receive++;
      }
    }
  }
  if(nb_args_to_receive==0){
    GRPC_RETURN(GRPC_NO_ERROR, GRPC_NO_MINOR_ERROR);
  }
#endif


  if(req->s_pid > 0)
    gs_req_child_waitpid(req, GS_WBLOCK);

  srv = req->handle->server_list[req->handle->srv_idx];

  sock = gs_connect_to_host(srv->componentid, srv->ipaddress,
                            srv->port, srv->proxyip, srv->proxyport);

  if(sock == INVALID_SOCKET)
    GRPC_RETURN(GRPC_COMMUNICATION_FAILED, GRPC_SERVER_CONNECTION);

  if((gs_send_tag(sock, GS_PROT_AWAIT_COMPLETION) < 0) ||
     (gs_send_string(sock, VERSION) < 0))
    goto error_communication_failed;

  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;

  if(tag != GS_PROT_OK) {
    if(tag == GS_PROT_VERSION_MISMATCH)
      grpc_minor_errno = GRPC_VERSION_MISMATCH;
    else
      grpc_minor_errno = GRPC_NO_MINOR_ERROR;

    GRPC_RETURN(GRPC_OTHER_ERROR_CODE, grpc_minor_errno);
  }

  if(gs_send_string(sock, req->request_id) < 0)
    goto error_communication_failed;


#ifdef GS_SMART_GRIDSOLVE
  
 /*
  * For each output argument send the variable output_arg_sent_remotely to 
  * the server. This specifies whether the output arg is sent remotely or
  * back to the client as outlined by the mapping solution.  
  */  

  for(argptr= req->handle->problem_desc->arglist;argptr!=NULL;argptr=argptr->next) {
    if(argptr->objecttype!=GS_SCALAR){
      if( ( argptr->inout==GS_INOUT ) || ( argptr->inout==GS_OUT ) ) {
        if(gs_send_int(sock, argptr->output_arg_sent_remotely) < 0) {
          ERRPRINTF("gs_send output remote param\n");
          return -1;         
        }
      }
    }
  }


#endif



  if(gs_wait_for_output(sock) < 0)
    goto error_communication_failed;

  if(gs_recv_tag(sock, &tag) < 0)
    goto error_communication_failed;

  if(tag != GS_PROT_OK) {
    ERRPRINTF("Service failed: %s\n", gs_service_error[tag]);
    grpc_minor_errno = tag;
    goto error_protocol_error;
  }



#ifdef GS_SMART_GRIDSOLVE
 /*
  * The client receives only the output arguments from the server
  * which have been outlined in the mapping solution.
  */
  
  if(gs_smart_recv_output_args_from_server(sock, req->problem, req->handle->problem_desc,
              req->handle->s