home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / test / io / bmi / test-bmi-server-list-gm.c < prev    next >
C/C++ Source or Header  |  2006-08-22  |  7KB  |  331 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7.  
  8.  
  9.  
  10. /*
  11.  * This is an example of a server program that uses the BMI 
  12.  * library for communications
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #include "bmi.h"
  22. #include "gossip.h"
  23. #include "test-bmi.h"
  24.  
  25. /**************************************************************
  26.  * Data structures 
  27.  */
  28.  
  29. /* A little structure to hold program options, either defaults or
  30.  * specified on the command line 
  31.  */
  32. struct options
  33. {
  34.     char *hostid;        /* host identifier */
  35. };
  36.  
  37. /**************************************************************
  38.  * Internal utility functions
  39.  */
  40.  
  41. static struct options *parse_args(
  42.     int argc,
  43.     char *argv[]);
  44.  
  45.  
  46. /**************************************************************/
  47.  
  48. int main(
  49.     int argc,
  50.     char **argv)
  51. {
  52.  
  53.     struct options *user_opts = NULL;
  54.     struct server_request *my_req = NULL;
  55.     struct server_ack *my_ack = NULL;
  56.     int ret = -1;
  57.     PVFS_BMI_addr_t client_addr;
  58.     void *recv_buffer1 = NULL;
  59.     void *recv_buffer2 = NULL;
  60.     bmi_op_id_t server_ops[2];
  61.     bmi_error_code_t error_code;
  62.     int outcount = 0;
  63.     struct BMI_unexpected_info request_info;
  64.     bmi_size_t actual_size;
  65.     bmi_size_t size_list[2];
  66.     void *buffer_list[2];
  67.     int last = 0;
  68.     int i = 0;
  69.     bmi_context_id context;
  70.  
  71.     /* grab any command line options */
  72.     user_opts = parse_args(argc, argv);
  73.     if (!user_opts)
  74.     {
  75.     return (-1);
  76.     }
  77.  
  78.     /* set debugging stuff */
  79.     gossip_enable_stderr();
  80.     gossip_set_debug_mask(1, GOSSIP_BMI_DEBUG_ALL);
  81.  
  82.  
  83.     /* initialize local interface (default options) */
  84.     ret = BMI_initialize("bmi_gm", user_opts->hostid, BMI_INIT_SERVER);
  85.     if (ret < 0)
  86.     {
  87.     errno = -ret;
  88.     perror("BMI_initialize");
  89.     return (-1);
  90.     }
  91.  
  92.     ret = BMI_open_context(&context);
  93.     if (ret < 0)
  94.     {
  95.     errno = -ret;
  96.     perror("BMI_open_context()");
  97.     return (-1);
  98.     }
  99.  
  100.     /* wait for an initial request  */
  101.     do
  102.     {
  103.     ret = BMI_testunexpected(1, &outcount, &request_info, 5000);
  104.     } while (ret == 0 && outcount == 0);
  105.     if (ret < 0)
  106.     {
  107.     fprintf(stderr, "Request recv failure (bad state).\n");
  108.     errno = -ret;
  109.     perror("BMI_testunexpected");
  110.     return (-1);
  111.     }
  112.     if (request_info.error_code != 0)
  113.     {
  114.     fprintf(stderr, "Request recv failure (bad state).\n");
  115.     return (-1);
  116.     }
  117.  
  118.     printf("Received a new request.\n");
  119.  
  120.     if (request_info.size != sizeof(struct server_request))
  121.     {
  122.     fprintf(stderr, "Bad Request!\n");
  123.     exit(-1);
  124.     }
  125.  
  126.     my_req = (struct server_request *) request_info.buffer;
  127.     client_addr = request_info.addr;
  128.  
  129.     /* create an ack */
  130.     my_ack = (struct server_ack *) BMI_memalloc(client_addr,
  131.                         sizeof(struct server_ack),
  132.                         BMI_SEND);
  133.     if (!my_ack)
  134.     {
  135.     fprintf(stderr, "BMI_memalloc failed.\n");
  136.     return (-1);
  137.     }
  138.     memset(my_ack, 0, sizeof(struct server_ack));
  139.  
  140.     /* post the ack */
  141.     buffer_list[0] = my_ack;
  142.     size_list[0] = sizeof(struct server_ack);
  143.  
  144.     ret = BMI_post_send_list(&(server_ops[1]), client_addr,
  145.                  (const void **) buffer_list, size_list, 1,
  146.                  sizeof(struct server_ack), BMI_PRE_ALLOC, 0, NULL,
  147.                  context);
  148.     if (ret < 0)
  149.     {
  150.     fprintf(stderr, "BMI_post_send_failure.\n");
  151.     return (-1);
  152.     }
  153.     if (ret == 0)
  154.     {
  155.     /* turning this into a blocking call for testing :) */
  156.     /* check for completion of ack send */
  157.     do
  158.     {
  159.         ret = BMI_test(server_ops[1], &outcount, &error_code,
  160.                &actual_size, NULL, 10, context);
  161.     } while (ret == 0 && outcount == 0);
  162.  
  163.     if (ret < 0 || error_code != 0)
  164.     {
  165.         fprintf(stderr, "ack send failed.\n");
  166.         return (-1);
  167.     }
  168.     }
  169.  
  170.     /* create 2 buffers to recv into */
  171.     recv_buffer1 = BMI_memalloc(client_addr, (my_req->size / 2), BMI_RECV);
  172.     recv_buffer2 = BMI_memalloc(client_addr,
  173.                 (my_req->size - (my_req->size / 2)), BMI_RECV);
  174.     if (!recv_buffer1 || !recv_buffer2)
  175.     {
  176.     fprintf(stderr, "BMI_memalloc failed.\n");
  177.     return (-1);
  178.     }
  179.     buffer_list[0] = recv_buffer1;
  180.     buffer_list[1] = recv_buffer2;
  181.     size_list[0] = my_req->size / 2;
  182.     size_list[1] = my_req->size - (my_req->size / 2);
  183.  
  184.     /* post the recv */
  185.     ret = BMI_post_recv_list(&(server_ops[0]), client_addr, buffer_list,
  186.                  size_list, 2, my_req->size, &actual_size,
  187.                  BMI_PRE_ALLOC, 0, NULL, context);
  188.     if (ret < 0)
  189.     {
  190.     fprintf(stderr, "BMI_post_recv_failure.\n");
  191.     return (-1);
  192.     }
  193.     if (ret == 0)
  194.     {
  195.     /* turning this into a blocking call for testing :) */
  196.     /* check for completion of data payload recv */
  197.     do
  198.     {
  199.         ret = BMI_test(server_ops[0], &outcount, &error_code,
  200.                &actual_size, NULL, 10, context);
  201.     } while (ret == 0 && outcount == 0);
  202.  
  203.     if (ret < 0 || error_code != 0)
  204.     {
  205.         fprintf(stderr, "data recv failed.\n");
  206.         return (-1);
  207.     }
  208.     }
  209.  
  210.     if (actual_size != my_req->size)
  211.     {
  212.     printf("Short recv.\n");
  213.     printf("diff: %d\n", (int) (my_req->size - actual_size));
  214.     }
  215.  
  216.     /* check validity of received message */
  217.     for (i = 0; i < ((my_req->size / 2) / sizeof(int)); i++)
  218.     {
  219.     if (((int *) recv_buffer1)[i] != i)
  220.     {
  221.         fprintf(stderr, "Validation failure, offset %d.\n", i);
  222.     }
  223.     }
  224.     last = i;
  225.     for (i = last;
  226.      i < (last + ((my_req->size - (my_req->size / 2)) / sizeof(int))); i++)
  227.     {
  228.     if (((int *) recv_buffer2)[i - last] != i)
  229.     {
  230.         fprintf(stderr, "Validation failure, offset %d.\n", i);
  231.     }
  232.     }
  233.  
  234.     /* free up the message buffers */
  235.     BMI_memfree(client_addr, recv_buffer1, (my_req->size / 2), BMI_RECV);
  236.     BMI_memfree(client_addr, recv_buffer2, (my_req->size -
  237.                         (my_req->size / 2)), BMI_RECV);
  238.     BMI_memfree(client_addr, my_ack, sizeof(struct server_ack), BMI_SEND);
  239.     BMI_unexpected_free(my_req);
  240.  
  241.     /* shutdown the local interface */
  242.     BMI_close_context(context);
  243.     ret = BMI_finalize();
  244.     if (ret < 0)
  245.     {
  246.     errno = -ret;
  247.     perror("BMI_finalize");
  248.     return (-1);
  249.     }
  250.  
  251.     /* turn off debugging stuff */
  252.     gossip_disable();
  253.  
  254.     free(user_opts->hostid);
  255.     free(user_opts);
  256.  
  257.     return (0);
  258. }
  259.  
  260.  
  261. static struct options *parse_args(
  262.     int argc,
  263.     char *argv[])
  264. {
  265.  
  266.     /* getopt stuff */
  267.     extern char *optarg;
  268.     char flags[] = "h:r:s:c:";
  269.     int one_opt = 0;
  270.  
  271.     struct options *tmp_opts = NULL;
  272.     int len = -1;
  273.  
  274.     /* create storage for the command line options */
  275.     tmp_opts = (struct options *) malloc(sizeof(struct options));
  276.     if (!tmp_opts)
  277.     {
  278.     goto parse_args_error;
  279.     }
  280.  
  281.     /* look at command line arguments */
  282.     while ((one_opt = getopt(argc, argv, flags)) != EOF)
  283.     {
  284.     switch (one_opt)
  285.     {
  286.     case ('h'):
  287.         len = (strlen(optarg)) + 1;
  288.         if ((tmp_opts->hostid = (char *) malloc(len)) == NULL)
  289.         {
  290.         goto parse_args_error;
  291.         }
  292.         memcpy(tmp_opts->hostid, optarg, len);
  293.         break;
  294.     default:
  295.         break;
  296.     }
  297.     }
  298.  
  299.     /* if we didn't get a host argument, fill in a default: */
  300.     len = (strlen(DEFAULT_SERVERID_GM)) + 1;
  301.     if ((tmp_opts->hostid = (char *) malloc(len)) == NULL)
  302.     {
  303.     goto parse_args_error;
  304.     }
  305.     memcpy(tmp_opts->hostid, DEFAULT_SERVERID_GM, len);
  306.  
  307.     return (tmp_opts);
  308.  
  309.   parse_args_error:
  310.  
  311.     /* if an error occurs, just free everything and return NULL */
  312.     if (tmp_opts)
  313.     {
  314.     if (tmp_opts->hostid)
  315.     {
  316.         free(tmp_opts->hostid);
  317.     }
  318.     free(tmp_opts);
  319.     }
  320.     return (NULL);
  321. }
  322.  
  323. /*
  324.  * Local variables:
  325.  *  c-indent-level: 4
  326.  *  c-basic-offset: 4
  327.  * End:
  328.  *
  329.  * vim: ts=8 sts=4 sw=4 expandtab
  330.  */
  331.