Guest User

Untitled

a guest
Jan 22nd, 2018
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.15 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <errno.h>
  6.  
  7. #include <limits.h>
  8. #include <stdutil/stdutil.h>
  9. #include <stdutil/stdhash.h>
  10. #include <stdutil/stddll.h>
  11. #include <stdutil/stderror.h>
  12.  
  13. #include "sp.h"
  14.  
  15. static char User[80];
  16. static char Spread_name[80];
  17. static mailbox Mbox;
  18. static int outputInterval;
  19. static char Private_group[MAX_GROUP_NAME];
  20.  
  21. static void parseArgs( int argc, char *argv[] );
  22. static void Print_help();
  23. static void showStats(stdhash* stats);
  24. static int group_name_ptr_cmp(const void *strptr1, const void *strptr2);
  25. static stdhcode group_name_hashcode(const void *str);
  26. static stdhcode group_name_ptr_hashcode(const void *strptr);
  27. static void incrementStats(stdhash* stats, char *key);
  28.  
  29. #define MY_MAX_NUM_GROUPS 1000
  30. #define MY_MAX_MESS_SIZE 102400
  31. static stddll wantedGroups;
  32.  
  33. int main( int argc, char *argv[] )
  34. {
  35. sp_time connect_timeout = { 0, 50*1000 };
  36. int ret;
  37.  
  38. parseArgs( argc, argv );
  39.  
  40. ret = SP_connect_timeout(Spread_name, User, 0, 1, &Mbox, Private_group, connect_timeout ) ;
  41. if(ret < 0)
  42. {
  43. SP_error(ret);
  44. return EXIT_FAILURE;
  45. }
  46. printf("Connected\n");
  47.  
  48. stdit hit;
  49. for (stddll_begin(&wantedGroups, &hit); !stddll_is_end(&wantedGroups, &hit); stddll_it_next(&hit)) {
  50. ret = SP_join( Mbox, *(char**)stddll_it_val(&hit));
  51. if(ret < 0)
  52. {
  53. SP_error(ret);
  54. return EXIT_FAILURE;
  55. }
  56. printf("Joined group %s\n", *(char**)stddll_it_val(&hit));
  57. }
  58.  
  59.  
  60. int mess_len;
  61. service service_type;
  62. char sender[MAX_GROUP_NAME];
  63. int num_groups;
  64. int16 mess_type;
  65. int endian_mismatch;
  66. char mess[MY_MAX_MESS_SIZE];
  67. long totalCounter = 0;
  68. stdhash groupCounter;
  69. struct timespec lastOutput;
  70.  
  71. if (clock_gettime(CLOCK_HIGHRES, &lastOutput) != 0) {
  72. printf("clock_gettime() error: %s\n", strerror(errno));
  73. }
  74.  
  75. stdhash_construct(&groupCounter, sizeof(char*), sizeof(long*),
  76. group_name_ptr_cmp, group_name_ptr_hashcode, 0);
  77.  
  78. while(1) {
  79. service_type = 0;
  80. char groupsArray[MY_MAX_NUM_GROUPS][MAX_GROUP_NAME];
  81.  
  82. int result;
  83. fd_set readset;
  84. struct timeval timeout = {0, 100*1000}; /* 0.1 sec */
  85.  
  86.  
  87. FD_ZERO(&readset);
  88. FD_SET(Mbox, &readset);
  89.  
  90. /* the non-zero timeout is important for making sure this loop doesn't tie up the CPU */
  91. /* it should be granular enough or rather smaller than the stats output interval */
  92. result = select(Mbox + 1, &readset, NULL, NULL, &timeout);
  93.  
  94. if (result == -1) {
  95. printf("select() error: %s\n", strerror(errno));
  96. return EXIT_FAILURE;
  97. } else {
  98. /* ready to read */
  99. if (FD_ISSET(Mbox, &readset)) {
  100. /* The Mbox has data available to be read */
  101. if ((mess_len = SP_receive(Mbox, &service_type, sender, MY_MAX_NUM_GROUPS,
  102. &num_groups, groupsArray, &mess_type, &endian_mismatch,
  103. MY_MAX_MESS_SIZE, mess)) < 0) {
  104. fprintf(stderr, "SP_receive failure: ");
  105. SP_error(mess_len);
  106. return EXIT_FAILURE;
  107. }
  108. if (Is_regular_mess(service_type)) {
  109. totalCounter++;
  110. int i;
  111. for (i = 0; i < num_groups; i++) {
  112. incrementStats(&groupCounter, groupsArray[i]);
  113. }
  114. }
  115. }
  116. struct timespec time;
  117. if (clock_gettime(CLOCK_HIGHRES, &time) != 0) {
  118. printf("clock_gettime() error: %s\n", strerror(errno));
  119. }
  120. if((lastOutput.tv_sec + outputInterval) < time.tv_sec) {
  121. showStats(&groupCounter);
  122. lastOutput.tv_sec = time.tv_sec;
  123. lastOutput.tv_nsec = time.tv_nsec;
  124. }
  125. }
  126. }
  127. stdhash_destruct(&groupCounter);
  128. stddll_destruct(&wantedGroups);
  129.  
  130. return EXIT_SUCCESS;
  131. }
  132.  
  133. static void parseArgs(int argc, char *argv[]) {
  134. /* Setting defaults */
  135. sprintf(User, "counter");
  136. sprintf(Spread_name, "4803@localhost");
  137. outputInterval = 5;
  138.  
  139. stddll_construct(&wantedGroups, sizeof(char*));
  140.  
  141. while( --argc > 0 )
  142. {
  143. argv++;
  144.  
  145. if (!strncmp( *argv, "-i", 2 )) {
  146. if (argc < 2) Print_help();
  147. outputInterval = atoi(argv[1]);
  148. argc--; argv++;
  149. } else if (!strncmp(*argv, "-u", 2)) {
  150. if (argc < 2) Print_help();
  151. strncpy(User, argv[1], 80);
  152. argc--; argv++;
  153. } else if (!strncmp(*argv, "-g", 2)) {
  154. if (argc < 2) Print_help();
  155. char *group;
  156. if ((group = malloc(MAX_GROUP_NAME)) == 0) {
  157. fprintf(stderr,"(%s, %d): malloc(%d) failed\n",
  158. __FILE__, __LINE__, MAX_GROUP_NAME);
  159. exit(EXIT_FAILURE);
  160. }
  161. memcpy(group, argv[1], MAX_GROUP_NAME);
  162.  
  163. int ret;
  164. if ((ret = stddll_push_back(&wantedGroups, &group)) != 0) {
  165. fprintf(stderr, "stddll_push() error: %s\n", stderr_strerr(ret));
  166. exit(EXIT_FAILURE);
  167. }
  168. argc--; argv++;
  169. } else if (!strncmp(*argv, "-s", 2)) {
  170. if (argc < 2) Print_help();
  171. strncpy(Spread_name, argv[1], 80);
  172. argc--; argv++;
  173. } else {
  174. Print_help();
  175. }
  176. }
  177. if (stddll_size(&wantedGroups) <= 0) {
  178. printf("Please specify at least one group to join.\n");
  179. Print_help();
  180. exit(EXIT_FAILURE);
  181. }
  182. if (outputInterval <= 0) {
  183. printf("The output interval must be greater than 0.\n");
  184. Print_help();
  185. exit(EXIT_FAILURE);
  186. }
  187. }
  188.  
  189. static void Print_help()
  190. {
  191. printf( "Usage: spcounter\n%s\n%s\n%s\n%s\n",
  192. "\t[-g <group name>] : message group name",
  193. "\t[-u <user name>] : unique Spread user name",
  194. "\t[-s <spread name>] : either port or port@machine",
  195. "\t[-i <seconds>] : statistics output interval");
  196. exit(EXIT_FAILURE);
  197. }
  198.  
  199. static void showStats(stdhash* stats) {
  200. if (stdhash_size(stats) < 1)
  201. return;
  202.  
  203. struct timespec time;
  204. if (clock_gettime(CLOCK_REALTIME, &time) != 0) {
  205. printf("clock_gettime() error: %s\n", strerror(errno));
  206. }
  207. printf("%li.%li - ", time.tv_sec, time.tv_nsec);
  208.  
  209. stdit hit;
  210. for (stdhash_begin(stats, &hit); !stdhash_is_end(stats, &hit); stdhash_it_next(&hit)) {
  211. if (!stdhash_is_begin(stats, &hit)) {
  212. printf(", ");
  213. }
  214. printf("%s %li", *(char**)stdhash_it_key(&hit), *(long*)stdhash_it_val(&hit));
  215. }
  216. printf("\n");
  217. }
  218.  
  219. static int group_name_ptr_cmp(const void *strptr1, const void *strptr2) {
  220. return strncmp(*(const char**) strptr1, *(const char**) strptr2, MAX_GROUP_NAME);
  221. }
  222.  
  223. static stdhcode group_name_hashcode(const void *str) {
  224. return stdhcode_sfh(str, strlen((const char*) str));
  225. }
  226.  
  227. static stdhcode group_name_ptr_hashcode(const void *strptr) {
  228. return group_name_hashcode(*(const void**) strptr);
  229. }
  230.  
  231. static void incrementStats(stdhash* stats, char *key) {
  232. stdit iter;
  233.  
  234. if (stdhash_is_end(stats, stdhash_find(stats, &iter, &key))) {
  235. long count = 1;
  236. char *group;
  237.  
  238. if ((group = malloc(MAX_GROUP_NAME)) == 0) {
  239. fprintf(stderr,"(%s, %d): malloc(%d) failed\n",
  240. __FILE__, __LINE__, MAX_GROUP_NAME);
  241. exit(EXIT_FAILURE);
  242. }
  243. memcpy(group, key, MAX_GROUP_NAME);
  244.  
  245. int ret;
  246. if ((ret = stdhash_insert(stats, 0, &group, &count)) != 0) {
  247. fprintf(stderr, "stdhash_insert() error: %s\n", stderr_strerr(ret));
  248. exit(EXIT_FAILURE);
  249. }
  250. } else {
  251. *(long*)stdhash_it_val(&iter) += 1;
  252. }
  253. }
Add Comment
Please, Sign In to add comment