static int dlist_int_test() { printf("double list test ... MAX=%d\n", MAX); int arr[MAX]; int i; int sum = 0; int max = INT_MIN; printf("MAX = %d\n", MAX); struct dlist *list = dlist_init(); if (list) { /* * init arr */ for (i = 0; i < MAX; i++) { arr[i] = i; } /* * dlist_add/dlist_length test */ for (i = 0; i < MAX; i++) { dlist_add(list, arr + i); assert(dlist_length(list) == i + 1); } /* * dlist_serch test */ for (i = 0; i < MAX; i++) { assert(dlist_search(list, arr + i) == DLIST_RET_OK); } /* * dlist_printf test */ assert(dlist_printf(list, user_printf) == DLIST_RET_OK); assert(dlist_foreach(list, sum_cb, &sum) == DLIST_RET_OK); assert(dlist_foreach(list, max_cb, &max) == DLIST_RET_OK); /* * dlist_delete test */ for (i = MAX - 1; i >= 0; i--) { assert(dlist_length(list) == i + 1); assert(dlist_delete(list, arr + i) == DLIST_RET_OK); assert(dlist_length(list) == i); } /* * dlist_destroy test */ assert(dlist_destroy(list) == DLIST_RET_OK); } printf("sum = %d\n", sum); printf("max = %d\n", max); return 0; }
static void test_int_dlist(void) { int i = 0; int n = 100; int data = 0; DList* dlist = dlist_create(NULL, NULL, NULL); for(i = 0; i < n; i++) { assert(dlist_append(dlist, (void*)i) == RET_OK); assert(dlist_length(dlist) == (i + 1)); assert(dlist_get_by_index(dlist, i, (void**)&data) == RET_OK); assert(data == i); assert(dlist_set_by_index(dlist, i, (void*)(2*i)) == RET_OK); assert(dlist_get_by_index(dlist, i, (void**)&data) == RET_OK); assert(data == 2*i); assert(dlist_set_by_index(dlist, i, (void*)i) == RET_OK); assert(dlist_find(dlist, cmp_int, (void*)i) == i); } for(i = 0; i < n; i++) { assert(dlist_get_by_index(dlist, 0, (void**)&data) == RET_OK); assert(data == (i)); assert(dlist_length(dlist) == (n-i)); assert(dlist_delete(dlist, 0) == RET_OK); assert(dlist_length(dlist) == (n-i-1)); if((i + 1) < n) { assert(dlist_get_by_index(dlist, 0, (void**)&data) == RET_OK); assert((int)data == (i+1)); } } assert(dlist_length(dlist) == 0); for(i = 0; i < n; i++) { assert(dlist_prepend(dlist, (void*)i) == RET_OK); assert(dlist_length(dlist) == (i + 1)); assert(dlist_get_by_index(dlist, 0, (void**)&data) == RET_OK); assert(data == i); assert(dlist_set_by_index(dlist, 0, (void*)(2*i)) == RET_OK); assert(dlist_get_by_index(dlist, 0, (void**)&data) == RET_OK); assert(data == 2*i); assert(dlist_set_by_index(dlist, 0, (void*)i) == RET_OK); } i = n - 1; assert(dlist_foreach(dlist, check_and_dec_int, &i) == RET_OK); dlist_destroy(dlist); return; }
/* FIXME */ void u_command(client c) { dstr pkey, skey; dlist_t dlist; if (dstr_length(c->argv[0]) == 1) { add_reply_error(c, "index can't be empty\r\n"); return; } pkey = dstr_new(c->argv[0] + 1); skey = dstr_new(pkey); if (c->argc > 1) { int i; for (i = 1; i < c->argc; ++i) { skey = dstr_cat(skey, ","); skey = dstr_cat(skey, c->argv[i]); } } table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey))) { struct kvd *kvd; if (NEW(kvd)) { dlist_node_t node, node2; kvd->key = skey; if ((node = dlist_find(dlist, kvd))) { FREE(kvd); kvd = (struct kvd *)dlist_node_value(node); if ((node2 = dlist_find(kvd->u.dlist, c))) dlist_remove(kvd->u.dlist, node2); if (dlist_length(kvd->u.dlist) == 0) { dlist_remove(dlist, node); kdfree(kvd); } if (dlist_length(dlist) == 0) { table_remove(subscribers, pkey); dlist_free(&dlist); } } else FREE(kvd); } else add_reply_error(c, "error allocating memory for kvd"); } table_rwlock_unlock(subscribers); dstr_free(skey); dstr_free(pkey); add_reply_string(c, "\r\n", 2); }
int parse_interval_qualifier(mvc *sql, struct dlist *pers, int *sk, int *ek, int *sp, int *ep) { *sk = iyear; *ek = isec; if (pers) { dlist *s = pers->h->data.lval; assert(s->h->type == type_int); *ek = *sk = s->h->data.i_val; *ep = *sp = s->h->next->data.i_val; if (dlist_length(pers) == 2) { dlist *e = pers->h->next->data.lval; assert(e->h->type == type_int); *ek = e->h->data.i_val; *ep = e->h->next->data.i_val; } } if (*sk > *ek) { snprintf(sql->errstr, ERRSIZE, _("End interval field is larger than the start field\n")); return -1; } if ((*sk == iyear || *sk == imonth) && *ek > imonth) { snprintf(sql->errstr, ERRSIZE, _("Correct interval ranges are year-month or day-seconds\n")); return -1; } if (*sk == iyear || *sk == imonth) return 0; return 1; }
Ret packet_transfer_reset(PacketTransfer *thiz) { return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS); int i; int j; int size; /* 删除命令集合中的所有命令 */ for (i = 0; i < NODE_NUM; i++) { size = dlist_length(thiz->command_set[i]); for (j = 0; i < size; j++) { dlist_delete(thiz->command_set[i], j); } } /* 重置回应 */ memset(&thiz->response, 0, sizeof(thiz->response)); /* 关闭与上位机连接 */ if (thiz->uploader_socket != -1) { close(thiz->uploader_socket); } thiz->uploader_socket = -1; return RET_OK; }
int dlist_insert(DList* thiz, int index, void* data) { DListNode* node = NULL; DListNode* cursor = NULL; if((node = dlist_node_create(data)) == NULL) return -1; if(thiz->first == NULL) { thiz->first = node; return 0; } cursor = dlist_get_node(thiz, index, 1); if(index < dlist_length(thiz)) { if(thiz->first == cursor) { thiz->first = node; } else { cursor->prev->next = node; node->prev = cursor->prev; } node->next = cursor; cursor->prev = node; } else { cursor->next = node; node->prev = cursor; } return 0; }
/* FIXME */ void uall_command(client c) { dstr res = get_indices(); dstr *fields = NULL; int nfield = 0, i; RTRIM(res); fields = dstr_split_len(res, dstr_length(res), ",", 1, &nfield); for (i = 1; i < nfield; ++i) { dstr pkey = dstr_new(fields[i]); dstr skey = dstr_new(pkey); dlist_t dlist; table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey))) { struct kvd *kvd; if (NEW(kvd)) { dlist_node_t node, node2; kvd->key = skey; if ((node = dlist_find(dlist, kvd))) { FREE(kvd); kvd = (struct kvd *)dlist_node_value(node); if ((node2 = dlist_find(kvd->u.dlist, c))) dlist_remove(kvd->u.dlist, node2); if (dlist_length(kvd->u.dlist) == 0) { dlist_remove(dlist, node); kdfree(kvd); } if (dlist_length(dlist) == 0) { table_remove(subscribers, pkey); dlist_free(&dlist); } } else FREE(kvd); } else add_reply_error(c, "error allocating memory for kvd"); } table_rwlock_unlock(subscribers); dstr_free(skey); dstr_free(pkey); } add_reply_string(c, "\r\n", 2); dstr_free(res); }
void list_plugins(const char *const nick) { notice(nick, "%d plugins loaded:", dlist_length(&plugins)); DLINK_FOREACH(node, dlist_head(&plugins)) { const struct plugin_handle_t *const p = dlink_data(node); notice(nick, "%s - %s", p->plugin->name, p->file_name); } }
void register_diff(Dlist* p_list, int descSock , char* reponse){ printf("Nouvelle connexion...\n"); int retour; char id [TAILLE_ID+1]; char ip1 [TAILLE_ADDRESS+1]; char port1 [TAILLE_PORT+1]; char ip2 [TAILLE_ADDRESS+1]; char port2 [TAILLE_PORT+1]; if (strlen(reponse) != 57){ printf("WARNING: Mauvais format REGI\n"); char regi_message[57]; format_regi(regi_message, reponse); strcpy(reponse, regi_message); } else if(dlist_length(p_list)>= NBR_DIFF){ retour = send(descSock, "RENO\r\n", strlen("RENO") + 2 * sizeof(char), 0); printf("Mauvais format de message reçu, reçu: %s\n", reponse); if (retour == -1){ perror (strerror (errno)); exit (1); } } snprintf(id, TAILLE_ID+1, "%s", reponse + REGI+1); if(verbose) printf("id : %s\n", id); snprintf(ip1, TAILLE_ADDRESS+1, "%s", reponse + REGI+1 + TAILLE_ID+1); if(verbose) printf("ip1 : %s\n", ip1); snprintf(port1, TAILLE_PORT+1, "%s", reponse + REGI+1 + TAILLE_ID+1 + TAILLE_ADDRESS+1); if(verbose) printf("port1 : %s\n", port1); snprintf(ip2, TAILLE_ADDRESS+1, "%s", reponse + REGI+1 + TAILLE_ID+1 + TAILLE_ADDRESS+1 + TAILLE_PORT+1); if(verbose) printf("ip2 : %s\n", ip2); snprintf(port2, TAILLE_PORT+1, "%s", reponse + REGI+1 + TAILLE_ID+1 + TAILLE_ADDRESS+1 + TAILLE_PORT+1 + TAILLE_ADDRESS+1); if(verbose) printf("port2 : %s\n", port2); struct node* p_new; if ((p_new = dlist_append(p_list, id, ip1, port1, ip2, port2)) != NULL){ retour = send(descSock, "REOK\r\n", strlen("REOK") + 2 * sizeof(char), 0); printf("REOK\n"); if (retour == -1){ perror (strerror (errno)); exit (1); } ask_RUOK(p_list, descSock, p_new); } else{ retour = send(descSock, "RENO\r\n", strlen("RENO") + 2 * sizeof(char), 0); printf("RENO\n"); } }
static int dlist_char_test() { char str[] = "dlist"; char str2[] = "thinking"; struct dlist *list = dlist_init(); assert(list != NULL); return_val_if_fail(dlist_length(list) == 0, -1); char *pstr = NULL; dlist_add(list, str); return_val_if_fail(dlist_length(list) == 1, -1); dlist_add(list, str2); dlist_add(list, pstr = strdup("test")); dlist_foreach(list, string_toupper_cb, NULL); dlist_printf(list, string_printf); dlist_destroy(list); list = NULL; free(pstr); return 0; }
static void* reader(void* param) { int i = 0; DList* dlist = (DList*)param; for (i = 0; i < NR; i++) { int length = dlist_length(dlist); dlist_find(dlist, cmp_int, (void*)i); } return NULL; }
int main() { struct DList* list = dlist_create(); dlist_print(list); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 5); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 7); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 8); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_remove(list, 1); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_insert(list, 0, 5); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_delete(list); return 0; }
Ret dlist_insert(DList* thiz, size_t index, void* data) { Ret ret = RET_OK; DListNode* node = NULL; DListNode* cursor = NULL; return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS); dlist_lock(thiz); do { if((node = dlist_create_node(thiz, data)) == NULL) { ret = RET_OOM; break; } if(thiz->first == NULL) { thiz->first = node; break; } cursor = dlist_get_node(thiz, index, 1); if(index < dlist_length(thiz)) { node->next = cursor; if(cursor->prev != NULL) { cursor->prev->next = node; } cursor->prev = node; if(thiz->first == cursor) { thiz->first = node; } } else { cursor->next = node; node->prev = cursor; } }while(0); dlist_unlock(thiz); return ret; }
static void *consumer_thread(void *arg) { int i = 0; DList *dlist = (DList *)arg; printf("consumer thread executed!\n"); for(i = 0; i < 2000; i++) { usleep(20); printf("dlist length = %d\n", dlist_length(dlist)); dlist_find(dlist, cmp_int, (void *)i); } return NULL; }
static void test_invalid_params(void) { printf("===========Warning is normal begin==============\n"); assert(dlist_length(NULL) == 0); assert(dlist_prepend(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_append(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_delete(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_insert(NULL, 0, 0) == RET_INVALID_PARAMS); assert(dlist_set_by_index(NULL, 0, 0) == RET_INVALID_PARAMS); assert(dlist_get_by_index(NULL, 0, NULL) == RET_INVALID_PARAMS); assert(dlist_find(NULL, NULL, NULL) < 0); assert(dlist_foreach(NULL, NULL, NULL) == RET_INVALID_PARAMS); printf("===========Warning is normal end==============\n"); return; }
size_t hash_table_length(HashTable* thiz) { size_t i = 0; size_t nr = 0; return_val_if_fail(thiz != NULL, 0); for(i = 0; i < thiz->slot_nr; i++) { if(thiz->slots[i] != NULL) { nr += dlist_length(thiz->slots[i]); } } return nr; }
/* * FUNCTION: compose_stripe_within_hba(devconfig_t *request, * dlist_t *hbas, uint64_t nbytes, * int maxcomp, int mincomp, dlist_t **stripe) * * INPUT: request - pointer to a devconfig_t of the current request * hbas - pointer to a list of available HBAs * nbytes - the desired capacity for the stripe * maxcomp - the maximum number of stripe components * mincomp - the minimum number of stripe components * * OUTPUT: stripe - pointer to a stripe devconfig_t result * * RETURNS: int - 0 on success * !0 otherwise. * * PURPOSE: Layout function which compose a stripe of the desired size * using available disks within any single HBA from the input list. * * The number of components within the composed stripe will be * in the range of min to max, preferring more components * over fewer. * * All input HBAs are expected to have at least mincomp * available disks and total space sufficient for the stripe. * * If the stripe can be composed, a pointer to it is returned in * the stripe devconfig_t *. * * * while (more hbas and stripe not composed) { * select HBA * if (not enough available space on this HBA) { * continue; * } * get available disks for HBA * use # disks as max # of stripe components * try to compose stripe * } * */ static int compose_stripe_within_hba( devconfig_t *request, dlist_t *hbas, uint64_t nbytes, uint16_t min, uint16_t max, devconfig_t **stripe) { int error = 0; dlist_t *iter = NULL; *stripe = NULL; for (iter = hbas; (iter != NULL) && (error == 0) && (*stripe == NULL); iter = iter->next) { dm_descriptor_t hba = (uintptr_t)iter->obj; dlist_t *disks = NULL; uint64_t space = 0; uint16_t ncomp = 0; char *name; ((error = get_display_name(hba, &name)) != 0) || (error = hba_get_avail_disks_and_space(request, hba, &disks, &space)); if (error == 0) { if (space >= nbytes) { ncomp = dlist_length(disks); ncomp = ((ncomp > max) ? max : ncomp); error = compose_stripe( request, nbytes, disks, ncomp, min, NULL, stripe); } else { print_hba_insufficient_space_msg(name, space); } } dlist_free_items(disks, NULL); } return (error); }
DListRet dlist_insert(DList* thiz, size_t index, void* data) { DListNode* node = NULL; DListNode* cursor = NULL; if((node = dlist_create_node(thiz, data)) == NULL) { return DLIST_RET_OOM; } if(thiz->first == NULL) { thiz->first = node; return DLIST_RET_OK; } cursor = dlist_get_node(thiz, index, 1); if(index < dlist_length(thiz)) { if(thiz->first == cursor) { thiz->first = node; } else { cursor->prev->next = node; node->prev = cursor->prev; } node->next = cursor; cursor->prev = node; } else { cursor->next = node; node->prev = cursor; } return DLIST_RET_OK; }
static void multi_thread_test(void) { pthread_t consumer_tid = 0; pthread_t producer_tid = 0; pthread_t reader_tid = 0; Locker* rw_locker = locker_pthread_create(); Locker* rd_locker = locker_pthread_create(); DList* dlist = dlist_create(NULL, NULL, rw_locker_create(rw_locker, rd_locker)); pthread_create(&producer_tid, NULL, producer, dlist); pthread_create(&consumer_tid, NULL, consumer, dlist); pthread_create(&reader_tid, NULL, reader, dlist); pthread_join(consumer_tid, NULL); pthread_join(producer_tid, NULL); pthread_join(reader_tid, NULL); printf("length=%d\n", dlist_length(dlist)); dlist_destroy(dlist); return; }
static int server_cron(event_loop el, unsigned long id, void *data) { dlist_iter_t iter; dlist_node_t node; NOT_USED(el); NOT_USED(id); NOT_USED(data); if (log_reload) { close_logger(); if (init_logger("/var/log/xcb/xcb-dp2.log", __LOG_DEBUG) == 0) { const char *tmp; pthread_mutex_lock(&cfg_lock); if ((tmp = variable_retrieve(cfg, "general", "log_level"))) { if (!strcasecmp(tmp, "debug")) set_logger_level(__LOG_DEBUG); else if (!strcasecmp(tmp, "info")) set_logger_level(__LOG_INFO); else if (!strcasecmp(tmp, "notice")) set_logger_level(__LOG_NOTICE); else if (!strcasecmp(tmp, "warning")) set_logger_level(__LOG_WARNING); } pthread_mutex_unlock(&cfg_lock); log_reload = 0; } /* FIXME */ if (addms) table_clear(times); } if (shut_down) { if (prepare_for_shutdown() == 0) exit(0); xcb_log(XCB_LOG_WARNING, "SIGTERM received, but errors trying to shutdown the server"); } /* FIXME */ iter = dlist_iter_new(clients_to_close, DLIST_START_HEAD); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); if (c->refcount == 0) client_free(c); } dlist_iter_free(&iter); /* FIXME */ if (cronloops % 200 == 0) { char meme[] = "SU OT GNOLEB ERA ESAB RUOY LLA"; int status; /* heartbeat */ dlist_lock(clients); if (dlist_length(clients) > 0) { dstr res = dstr_new("HEARTBEAT|"); dstr ip = getipv4(); res = dstr_cat(res, ip); res = dstr_cat(res, "\r\n"); iter = dlist_iter_new(clients, DLIST_START_HEAD); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (net_try_write(c->fd, res, dstr_length(res), 100, NET_NONBLOCK) == -1) xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); dstr_free(ip); dstr_free(res); } dlist_unlock(clients); /* FIXME: trying to lower the high CPU load while idle */ if ((status = pgm_send(pgm_sender, meme, sizeof meme, NULL)) != PGM_IO_STATUS_NORMAL) xcb_log(XCB_LOG_WARNING, "Communication test failed"); } ++cronloops; return 100; }
/* * FUNCTION: layout_stripe(devconfig_t *request, uint64_t nbytes, * dlist_t **results) * * INPUT: request - pointer to a devconfig_t of the current request * nbytes - the desired capacity of the stripe * * OUPUT: results - pointer to a list of composed volumes * * RETURNS: int - 0 on success * !0 otherwise. * * PURPOSE: Main layout driver for composing stripe volumes. * * Attempts to construct a stripe of size nbytes. * * Basic goal of all strategies is to build wide-thin stripes: * build widest stripe possible across as many HBAs as possible. * * Several different layout strategies are tried in order * of preference until one succeeds or there are none left. * * 1 - stripe across similar HBAs * . number of components is driven by # of HBAs * . requires mincomp available HBAs * * 2 - stripe within a single HBA * . number of components is driven by # of disks * . requires at least 1 HBA with mincomp disks * * 3 - stripe across all available disks on similar HBAs * . number of components is driven by # of disk * . requires at least mincomp disks * * 4 - stripe across all available HBAs * . number of components is driven by # of HBAs * . requires at least mincomp HBAs * * 5 - stripe across all available disks on all HBAs * . number of components is driven by # of disks * . requires at least mincomp disks * * Each strategy tries to compose a stripe with the * maximum number of components first then reduces the * number of components down to mincomp. * * get allowed minimum number of stripe components * get allowed maximum number of stripe components * get available HBAs * * group HBAs by characteristics * for (each HBA grouping) and (stripe not composed) { * select next HBA group * for (strategy[1,2,3]) and (stripe not composed) { * compose stripe using HBAs in group * } * } * * if (stripe not composed) { * for (strategy[4,5]) and (stripe not composed) { * compose stripe using all HBAs * } * } * * if (stripe composed) { * append composed stripe to results * } * */ int layout_stripe( devconfig_t *request, uint64_t nbytes, dlist_t **results) { /* * these enums define the # of strategies and the preference order * in which they are tried */ typedef enum { STRIPE_ACROSS_SIMILAR_HBAS_DISK_PER = 0, STRIPE_WITHIN_SIMILAR_HBA, STRIPE_ACROSS_SIMILAR_HBAS, N_SIMILAR_HBA_STRATEGIES } similar_hba_strategy_order_t; typedef enum { STRIPE_ACROSS_ANY_HBAS_DISK_PER = 0, STRIPE_ACROSS_ANY_HBAS, N_ANY_HBA_STRATEGIES } any_hba_strategy_order_t; dlist_t *usable_hbas = NULL; dlist_t *similar_hba_groups = NULL; dlist_t *iter = NULL; devconfig_t *stripe = NULL; uint16_t mincomp = 0; uint16_t maxcomp = 0; int error = 0; (error = get_usable_hbas(&usable_hbas)); if (error != 0) { return (error); } print_layout_volume_msg(devconfig_type_to_str(TYPE_STRIPE), nbytes); if (dlist_length(usable_hbas) == 0) { print_no_hbas_msg(); volume_set_error(gettext("There are no usable HBAs.")); return (-1); } ((error = group_similar_hbas(usable_hbas, &similar_hba_groups)) != 0) || /* * determine the min/max number of stripe components * based on the request, the diskset defaults or the * global defaults. These are absolute limits, the * actual values are determined by the number of HBAs * and/or disks available. */ (error = get_stripe_min_comp(request, &mincomp)) || (error = get_stripe_max_comp(request, &maxcomp)); if (error != 0) { return (error); } for (iter = similar_hba_groups; (error == 0) && (stripe == NULL) && (iter != NULL); iter = iter->next) { dlist_t *hbas = (dlist_t *)iter->obj; similar_hba_strategy_order_t order; for (order = STRIPE_ACROSS_SIMILAR_HBAS_DISK_PER; (order < N_SIMILAR_HBA_STRATEGIES) && (stripe == NULL) && (error == 0); order++) { dlist_t *selhbas = NULL; dlist_t *disks = NULL; int n = 0; switch (order) { case STRIPE_ACROSS_SIMILAR_HBAS_DISK_PER: error = select_hbas_with_n_disks( request, hbas, 1, &selhbas, &disks); if (error == 0) { /* BEGIN CSTYLED */ oprintf(OUTPUT_TERSE, gettext(" -->Strategy 1: use 1 disk from %d-%d similar HBAs - stripe across HBAs\n"), mincomp, maxcomp); /* END CSTYLED */ if ((n = dlist_length(selhbas)) >= mincomp) { n = ((n > maxcomp) ? maxcomp : n); error = compose_stripe( request, nbytes, disks, n, mincomp, NULL, &stripe); } else { print_insufficient_hbas_msg(n); } } break; case STRIPE_WITHIN_SIMILAR_HBA: error = select_hbas_with_n_disks( request, hbas, mincomp, &selhbas, &disks); if (error == 0) { /* BEGIN CSTYLED */ oprintf(OUTPUT_TERSE, gettext(" -->Strategy 2: use %d-%d disks from any single HBA - stripe within HBA\n"), mincomp, maxcomp); /* END CSTYLED */ if ((n = dlist_length(selhbas)) > 0) { error = compose_stripe_within_hba( request, selhbas, nbytes, mincomp, maxcomp, &stripe); } else { print_insufficient_disks_msg(n); } } break; case STRIPE_ACROSS_SIMILAR_HBAS: error = select_hbas_with_n_disks( request, hbas, 1, &selhbas, &disks); if (error == 0) { /* BEGIN CSTYLED */ oprintf(OUTPUT_TERSE, gettext(" -->Strategy 3: use %d-%d disks from %d similar HBAs - stripe across HBAs\n"), mincomp, maxcomp, dlist_length(hbas)); /* END CSTYLED */ if ((n = dlist_length(selhbas)) > 0) { if ((n = dlist_length(disks)) >= mincomp) { n = ((n > maxcomp) ? maxcomp : n); error = compose_stripe( request, nbytes, disks, n, mincomp, NULL, &stripe); } else { print_insufficient_disks_msg(n); } } else { print_insufficient_hbas_msg(n); } } break; default: break; } dlist_free_items(disks, NULL); dlist_free_items(selhbas, NULL); } } for (iter = similar_hba_groups; iter != NULL; iter = iter->next) { dlist_free_items((dlist_t *)iter->obj, NULL); } dlist_free_items(similar_hba_groups, NULL); /* * if striping within similar HBA groups failed, * try across all available HBAs */ if ((stripe == NULL) && (error == 0)) { any_hba_strategy_order_t order; for (order = STRIPE_ACROSS_ANY_HBAS_DISK_PER; (order < N_ANY_HBA_STRATEGIES) && (stripe == NULL) && (error == 0); order++) { dlist_t *selhbas = NULL; dlist_t *disks = NULL; int n = 0; switch (order) { case STRIPE_ACROSS_ANY_HBAS_DISK_PER: error = select_hbas_with_n_disks( request, usable_hbas, 1, &selhbas, &disks); if (error == 0) { /* BEGIN CSTYLED */ oprintf(OUTPUT_TERSE, gettext(" -->Strategy 4: use 1 disk from %d-%d available HBAs - stripe across any HBAs\n"), mincomp, maxcomp); /* END CSTYLED */ if ((n = dlist_length(selhbas)) >= mincomp) { n = ((n > maxcomp) ? maxcomp : n); error = compose_stripe( request, nbytes, disks, n, mincomp, NULL, &stripe); } else { print_insufficient_hbas_msg(n); } } break; case STRIPE_ACROSS_ANY_HBAS: error = select_hbas_with_n_disks( request, usable_hbas, 1, &selhbas, &disks); if (error == 0) { /* BEGIN CSTYLED */ oprintf(OUTPUT_TERSE, gettext(" -->Strategy 5: use %d-%d disks from %d available HBA - stripe across any HBAs\n"), mincomp, maxcomp, dlist_length(selhbas)); /* END CSTYLED */ if ((n = dlist_length(disks)) >= mincomp) { n = ((n > maxcomp) ? maxcomp : n); error = compose_stripe( request, nbytes, disks, n, mincomp, NULL, &stripe); } else { print_insufficient_disks_msg(n); } } break; } dlist_free_items(disks, NULL); dlist_free_items(selhbas, NULL); } } if (stripe != NULL) { dlist_t *item = NULL; if ((item = dlist_new_item(stripe)) == NULL) { error = ENOMEM; } else { *results = dlist_append(item, *results, AT_TAIL); print_layout_success_msg(); } } else if (error != 0) { print_debug_failure_msg( devconfig_type_to_str(TYPE_STRIPE), get_error_string(error)); } else { print_insufficient_resources_msg( devconfig_type_to_str(TYPE_STRIPE)); error = -1; } return (error); }
/* THE MAIN */ int main (const int argc, const char * argv[]) { /* Socket data */ soc_token soc = init_soc; soc_host lan; soc_port port; int soc_fd, fd; /* Socket message */ msg_type msg; /* Times and timeouts */ timeout_t start_time, end_time, current_time; timeout_t wait_timeout; double local_time, remote_time; /* Dynamic list of server infos */ dlist list; info_type info; /* Utilities */ boolean for_read; char buff[256]; int res; char *index; /*********/ /* Start */ /*********/ /* Save prog name */ strcpy (prog, argv[0]); strcpy (prog, basename (prog)); /*******************/ /* Parse arguments */ /*******************/ /* Check args */ if (argc != 2) { error ("Invalid argument"); } /* Parse IPM address and port */ strcpy (buff, argv[1]); index = strstr (buff, ":"); if (index == NULL) { error ("Invalid argument"); } *index = '\0'; index++; if (soc_str2host (buff, &lan) != SOC_OK) { sprintf (buff, "Invalid ipm address %s", buff); error (buff); } if (soc_str2port (index, &port) != SOC_OK) { sprintf (buff, "Invalid port num %s", index); error (buff); } /**************/ /* Initialize */ /**************/ /* Init dynamic list */ dlist_init (& list, sizeof(info_type)); /* Init socket */ if (soc_open (&soc, udp_socket) != SOC_OK) { perror ("opening socket"); error ("Socket initialization failed"); } if (soc_set_dest_host_port (soc, &lan, port) != SOC_OK) { perror ("setting destination"); error ("Socket initialization failed"); } if (soc_link_port (soc, port) != SOC_OK) { perror ("linking to port"); error ("Socket initialization failed"); } if (soc_get_dest_host (soc, &lan) != SOC_OK) { perror ("getting dest lan"); error ("Socket initialization failed"); } if (soc_get_dest_port (soc, &port) != SOC_OK) { perror ("getting dest port"); error ("Socket initialization failed"); } /* Add socket to waiting point */ if (soc_get_id(soc, &soc_fd) != SOC_OK) { perror ("getting socket id"); error ("Socket initialization failed"); } if (evt_add_fd(soc_fd, TRUE) != WAIT_OK) { perror("Adding fd"); error ("Socket initialization failed"); } /* Activate signal catching */ activate_signal_handling(); /* Report starting */ buff[0]='\0'; addr_image (&lan, buff); printf ("%s mcasting at address %s on port %d.\n", prog, buff, (int) port); /* Init times */ get_time (&start_time); current_time = start_time; end_time = start_time; incr_time (&end_time, DELAY_CLIENT_MS); /* Send initial ping request */ msg.ping = TRUE; msg.time = start_time; if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) { perror ("sending ping"); error ("Sending ping request failed"); } /*************/ /* Main loop */ /*************/ for (;;) { /* First step is to loop until timeout */ if (wait_timeout.tv_sec != -1) { wait_timeout = end_time; res = sub_time (&wait_timeout, ¤t_time); if (res <= 0) { break; } } if (evt_wait (&fd, &for_read, &wait_timeout) != WAIT_OK) { perror ("waiting for event"); error ("Waiting for events failed"); } if (! for_read) { error ("Write event received"); } /* Termination signal */ if (fd == SIG_EVENT) { if (get_signal () == SIG_TERMINATE) { break; } } else if (fd == NO_EVENT) { /* Timeout: first step ends with a dump of servers */ if (dlist_length(&list) != 0) { dlist_rewind (&list, TRUE); for (;;) { dlist_read (&list, &info); /* Get host name if possible, else dump address */ res = soc_host_name_of (&info.host, buff, sizeof(buff)); if (res != SOC_OK) { buff[0]='\0'; addr_image (&info.host, buff); } /* Compute (Start_time + Reception_time) / 2 */ local_time = (time_to_double (&start_time) + time_to_double (&info.reception_time) ) / 2.0; remote_time = time_to_double (&info.server_time); printf ("Host %s is shifted by %4.03fs\n", buff, remote_time - local_time); /* Done when last record has been put */ if (dlist_get_pos (&list, FALSE) == 1) { break; } dlist_move (&list, TRUE); } } /* Now entering second step: infinite timeout */ wait_timeout.tv_sec = -1; wait_timeout.tv_usec = -1; printf ("%s ready.\n", prog); } else if (fd != soc_fd) { sprintf (buff, "Invalid fd %d received", fd); error (buff); } else { /* Now this is the socket, read message */ res = soc_receive (soc, (soc_message) &msg, sizeof(msg), TRUE); if (res < 0) { perror ("reading from socket"); error ("Reading message failed"); } else if (res != sizeof(msg)) { sprintf (buff, "Invalid size received, expected %d, got %d", (int)sizeof(msg), res); error (buff); } get_time (¤t_time); /* Client and server different behaviours */ if ((wait_timeout.tv_sec != -1) && !msg.ping) { /* First step: store the address and time of server, if pong */ if (soc_get_dest_host (soc, &(info.host)) != SOC_OK) { perror ("getting dest host"); error ("Getting server address failed"); } info.server_time = msg.time; info.reception_time = current_time; dlist_insert (&list, &info, TRUE); } else if ( (wait_timeout.tv_sec == -1) && msg.ping) { /* Second step: reply pong and time to ping */ msg.time = current_time; msg.ping = FALSE; if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) { perror ("sending pong"); error ("Sending pong request failed"); } } } } /* End of main loop */ /* Clean - Close */ dlist_delete_all (&list); (void) evt_del_fd (soc_fd, TRUE); (void) soc_close (&soc); printf ("Done.\n"); exit (0); }
#include "helpers.h" TEST(copy_works_on_empty_list) { USING(dlist_new(sizeof(int))) { dlist_t *copy = dlist_copy(list); assertEquals(dlist_length(copy), 0); assertEquals(dlist_size(copy), dlist_size(list)); assertEquals(dlist_verify(copy), 0); dlist_free(copy); } USING(dlist_new(sizeof(float))) { dlist_t *copy = dlist_copy(list); assertEquals(dlist_length(copy), 0); assertEquals(dlist_size(copy), dlist_size(list)); assertEquals(dlist_verify(copy), 0); dlist_free(copy); } } TEST(copy_works_on_full_list) { int one = 1, two = 2, three = 3, four = 4; USING(dlist_new(sizeof(int))) { dlist_append(list, &one); dlist_t *copy = dlist_copy(list); assertNotEquals(copy, NULL); assertEquals(dlist_verify(copy), 0); assertEquals(dlist_length(copy), dlist_length(list)); assertEquals(dlist_size(copy), dlist_size(list));
int test_dlist() { puts("##########################################"); puts("starting double linked list tests"); puts("##########################################"); int value = 0; struct DList *dlist = dlist_create(); puts("empty double list created"); if (dlist_length(dlist) != 0) { printf("dlist_length of empty list should be zero\n"); return 0; } puts("dlist_length ok"); // Insert value 101 and test functions dlist_insert(dlist, 0, 101); if (dlist_length(dlist) != 1) { printf("dlist_length should be 1\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_get (1)\n"); return 0; } if (value != 101) { printf("dlist_get should return value 101\n"); return 0; } // Insert value 202 and test functions dlist_insert(dlist, 0, 202); if (dlist_length(dlist) != 2) { printf("dlist_length should return 2\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_length (2)\n"); return 0; } if (value != 202) { printf("dlist_get should return 202\n"); return 0; } puts("dlist_get ok"); // Test remove function if (dlist_remove(dlist, 1) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 1) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } puts("dlist_remove ok"); // test dlist_append() dlist_append(dlist, -5); dlist_append(dlist, 1); dlist_append(dlist, 15); if (dlist_length(dlist) != 3) { printf("dlist_length should return 0\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != -5) { printf("dlist_get should return -5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 1) { printf("dlist_get should return 1\n"); return 0; } if (dlist_get(dlist, 2, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 15) { printf("dlist_get should return 15\n"); return 0; } puts("dlist_append ok"); // test dlist insert dlist_insert(dlist, -5, 0); if (dlist_length(dlist) != 4) { printf("dlist_length should return 4\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 0) { printf("dlist_get should return 0\n"); return 0; } dlist_insert(dlist, 1, 100); if (dlist_length(dlist) != 5) { printf("dlist_length should return 5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 100) { printf("dlist_get should return 100\n"); return 0; } dlist_insert(dlist, 10, 500); if (dlist_length(dlist) != 6) { printf("dlist_length should return 6\n"); return 0; } if (dlist_get(dlist, 5, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 500) { printf("dlist_get should return 500\n"); return 0; } puts("dlist_insert ok"); // test print and print reversed puts("print current dlist"); dlist_print(dlist); puts("printing reversed dlist"); dlist_print_reverse(dlist); puts("check print and print_reversed for yourself!"); puts("##########################################"); puts("all tests of double linked lists completed"); puts("##########################################"); puts("------------------------------------------"); dlist_delete(dlist); return 1; }
#include "helpers.h" TEST(purge_does_nothing_on_empty_list) { USING(dlist_new(sizeof(int))) { assertEquals(dlist_purge(list), list); assertEquals(dlist_length(list), 0); assertEquals(dlist_size(list), sizeof(int)); } } TEST(purge_removes_all_elements_of_list) { USING(dlist_new(sizeof(int))) { assertNotEquals(dlist_append(list, NULL), NULL); assertEquals(dlist_length(list), 1); assertEquals(dlist_purge(list), list); assertEquals(dlist_length(list), 0); assertEquals(dlist_size(list), sizeof(int)); } USING(dlist_new(sizeof(int))) { assertNotEquals(dlist_append(list, NULL), NULL); assertNotEquals(dlist_append(list, NULL), NULL); assertEquals(dlist_length(list), 2); assertEquals(dlist_purge(list), list); assertEquals(dlist_length(list), 0); assertEquals(dlist_size(list), sizeof(int)); } USING(dlist_new(sizeof(int))) { assertNotEquals(dlist_append(list, NULL), NULL);
/* SET variable = value and set (variable1, .., variableN) = (query) */ static sql_exp * psm_set_exp(mvc *sql, dnode *n) { symbol *val = n->next->data.sym; sql_exp *e = NULL; int level = 0, is_last = 0; sql_subtype *tpe = NULL; sql_rel *rel = NULL; sql_exp *res = NULL; int single = (n->type == type_string); if (single) { exp_kind ek = {type_value, card_value, FALSE}; const char *name = n->data.sval; /* name can be 'parameter of the function' (ie in the param list) or a local or global variable, declared earlier */ /* check if variable is known from the stack */ if (!stack_find_var(sql, name)) { sql_arg *a = sql_bind_param(sql, name); if (!a) /* not parameter, ie local var ? */ return sql_error(sql, 01, SQLSTATE(42000) "Variable %s unknown", name); tpe = &a->type; } else { tpe = stack_find_type(sql, name); } e = rel_value_exp2(sql, &rel, val, sql_sel, ek, &is_last); if (!e || (rel && e->card > CARD_AGGR)) return NULL; level = stack_find_frame(sql, name); e = rel_check_type(sql, tpe, e, type_cast); if (!e) return NULL; if (rel) { sql_exp *er = exp_rel(sql, rel); list *b = sa_list(sql->sa); append(b, er); append(b, exp_set(sql->sa, name, e, level)); res = exp_rel(sql, rel_psm_block(sql->sa, b)); } else { res = exp_set(sql->sa, name, e, level); } } else { /* multi assignment */ exp_kind ek = {type_value, (single)?card_column:card_relation, FALSE}; sql_rel *rel_val = rel_subquery(sql, NULL, val, ek, APPLY_JOIN); dlist *vars = n->data.lval; dnode *m; node *n; list *b; if (!rel_val || !is_project(rel_val->op) || dlist_length(vars) != list_length(rel_val->exps)) { return sql_error(sql, 02, SQLSTATE(42000) "SET: Number of variables not equal to number of supplied values"); } b = sa_list(sql->sa); if (rel_val) { sql_exp *er = exp_rel(sql, rel_val); append(b, er); } for(m = vars->h, n = rel_val->exps->h; n && m; n = n->next, m = m->next) { char *vname = m->data.sval; sql_exp *v = n->data; if (!stack_find_var(sql, vname)) { sql_arg *a = sql_bind_param(sql, vname); if (!a) /* not parameter, ie local var ? */ return sql_error(sql, 01, SQLSTATE(42000) "Variable %s unknown", vname); tpe = &a->type; } else { tpe = stack_find_type(sql, vname); } if (!exp_name(v)) exp_label(sql->sa, v, ++sql->label); v = exp_column(sql->sa, exp_relname(v), exp_name(v), exp_subtype(v), v->card, has_nil(v), is_intern(v)); level = stack_find_frame(sql, vname); v = rel_check_type(sql, tpe, v, type_cast); if (!v) return NULL; if (v->card > CARD_AGGR) { sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(v)); assert(zero_or_one); v = exp_aggr1(sql->sa, v, zero_or_one, 0, 0, CARD_ATOM, 0); } append(b, exp_set(sql->sa, vname, v, level)); } res = exp_rel(sql, rel_psm_block(sql->sa, b)); } return res; }
void process_quote(void *data) { Quote *quote; struct msg *msg; quote = (Quote *)data; if (quote->thyquote.m_nLen == sizeof (tHYQuote)) { dlist_iter_t iter; dlist_node_t node; int tlen; quote->thyquote.m_cJYS[sizeof quote->thyquote.m_cJYS - 1] = '\0'; quote->thyquote.m_cHYDM[sizeof quote->thyquote.m_cHYDM - 1] = '\0'; quote->m_nMSec = 0; /* in case of multiple monitors */ dlist_rwlock_rdlock(monitors); if (dlist_length(monitors) > 0) { char res[512]; snprintf(res, sizeof res, "RX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%.2f,%.2f,%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n", quote->thyquote.m_nTime, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); iter = dlist_iter_new(monitors, DLIST_START_HEAD); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (!(c->flags & CLIENT_CLOSE_ASAP)) { if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 3) client_free_async(c); } else if (c->eagcount) c->eagcount = 0; } pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); } dlist_rwlock_unlock(monitors); /* FIXME */ if (quote->thyquote.m_nTime == 999999999) { FREE(data); return; /* idiosyncrasy of different timestamps */ } else if ((tlen = intlen(quote->thyquote.m_nTime)) < 10) { int hour; struct tm lt; hour = quote->thyquote.m_nTime / 10000000; if (tv.tv_sec == 0 || hour == 9 || hour == 21) gettimeofday(&tv, NULL); if (prev_hour == 23 && hour == 0) tv.tv_sec += 24 * 60 * 60; prev_hour = hour; localtime_r(&tv.tv_sec, <); if (quote->thyquote.m_cHYDM[0] == 'S' && quote->thyquote.m_cHYDM[1] == 'P') quote->thyquote.m_nTime *= 1000; else if (tlen == 6 || tlen == 7) quote->thyquote.m_nTime *= 100; lt.tm_sec = quote->thyquote.m_nTime % 100000 / 1000; lt.tm_min = quote->thyquote.m_nTime % 10000000 / 100000; lt.tm_hour = hour; quote->m_nMSec = quote->thyquote.m_nTime % 1000; quote->thyquote.m_nTime = mktime(<); } /* FIXME: no millisecond field in some exchanges' quotes */ if (addms) { struct timeval tv; dstr contract = dstr_new(quote->thyquote.m_cHYDM); struct sms *sms; gettimeofday(&tv, NULL); if ((sms = table_get_value(times, contract)) == NULL) { if (NEW(sms)) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; table_insert(times, contract, sms); } } else if (sms->qsec != quote->thyquote.m_nTime) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; dstr_free(contract); } else { int32_t offset; if ((offset = (tv.tv_sec - sms->sec) * 1000 + tv.tv_usec / 1000 - sms->msec) > 999) offset = 999; quote->m_nMSec = offset; dstr_free(contract); } } if (get_logger_level() == __LOG_DEBUG) { time_t t = (time_t)quote->thyquote.m_nTime; char datestr[64]; strftime(datestr, sizeof datestr, "%F %T", localtime(&t)); xcb_log(XCB_LOG_DEBUG, "%s.%03d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%d,%.2f,%d,%d,%.2f,%d,%.2f,%d", datestr, quote->m_nMSec, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); } } else xcb_log(XCB_LOG_DEBUG, "Data '%s' received", data); if (NEW0(msg) == NULL) { FREE(data); return; } msg->data = data; msg->refcount = 1; thrpool_queue(tp, send_quote, msg, NULL, msgfree, NULL); }
static int send_quote(void *data, void *data2) { struct msg *msg = (struct msg *)data; Quote *quote; int status; NOT_USED(data2); quote = (Quote *)msg->data; if (quote->thyquote.m_nLen == sizeof (THYQuote)) { if (get_logger_level() == __LOG_DEBUG) { time_t t = (time_t)quote->thyquote.m_nTime; char datestr[64]; strftime(datestr, sizeof datestr, "%F %T", localtime(&t)); xcb_log(XCB_LOG_DEBUG, "%s.%03d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%d,%.2f,%d,%d,%.2f,%d,%.2f,%d", datestr, quote->m_nMSec, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); } /* for testing */ dlist_rwlock_rdlock(monitors); if (dlist_length(monitors) > 0) { char res[512]; dlist_iter_t iter = dlist_iter_new(monitors, DLIST_START_HEAD); dlist_node_t node; snprintf(res, sizeof res, "TX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n", quote->thyquote.m_nTime, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (c->flags & CLIENT_CLOSE_ASAP) { pthread_spin_unlock(&c->lock); continue; } if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 10) client_free_async(c); } else if (c->eagcount) c->eagcount = 0; pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); } dlist_rwlock_unlock(monitors); } /* FIXME */ if ((status = pgm_send(pgm_sender, msg->data, sizeof (Quote), NULL)) != PGM_IO_STATUS_NORMAL) xcb_log(XCB_LOG_WARNING, "Sending data failed"); msg_decr(msg); return 0; }
static size_t linear_container_dlist_length(LinearContainer* thiz) { PrivInfo* priv = (PrivInfo*)thiz->priv; return dlist_length(priv->dlist); }
static void read_quote(event_loop el, int fd, int mask, void *data) { char *buf; struct sockaddr_in si; socklen_t slen = sizeof si; int nread; NOT_USED(el); NOT_USED(mask); NOT_USED(data); if ((buf = CALLOC(1, sizeof (Quote))) == NULL) return; /* FIXME */ if ((nread = recvfrom(fd, buf, sizeof (Quote), 0, (struct sockaddr *)&si, &slen)) > 0) { Quote *quote; struct msg *msg; quote = (Quote *)buf; if (quote->thyquote.m_nLen == sizeof (THYQuote)) { int tlen; quote->thyquote.m_cJYS[sizeof quote->thyquote.m_cJYS - 1] = '\0'; quote->thyquote.m_cHYDM[sizeof quote->thyquote.m_cHYDM - 1] = '\0'; quote->m_nMSec = 0; /* for testing */ dlist_rwlock_rdlock(monitors); if (dlist_length(monitors) > 0) { char res[512]; dlist_iter_t iter = dlist_iter_new(monitors, DLIST_START_HEAD); dlist_node_t node; snprintf(res, sizeof res, "RX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%.2f,%.2f,%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n", quote->thyquote.m_nTime, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (c->flags & CLIENT_CLOSE_ASAP) { pthread_spin_unlock(&c->lock); continue; } if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 10) client_free_async(c); } else if (c->eagcount) c->eagcount = 0; pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); } dlist_rwlock_unlock(monitors); /* FIXME */ if (quote->thyquote.m_nTime == 999999999) { FREE(buf); return; } else if ((tlen = intlen(quote->thyquote.m_nTime)) < 10) { struct timeval tv; struct tm lt; gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, <); if (quote->thyquote.m_cHYDM[0] == 'S' && quote->thyquote.m_cHYDM[1] == 'P') quote->thyquote.m_nTime *= 1000; else if (tlen == 6 || tlen == 7) quote->thyquote.m_nTime *= 100; lt.tm_hour = quote->thyquote.m_nTime / 10000000; lt.tm_min = quote->thyquote.m_nTime % 10000000 / 100000; lt.tm_sec = quote->thyquote.m_nTime % 100000 / 1000; quote->m_nMSec = quote->thyquote.m_nTime % 1000; quote->thyquote.m_nTime = mktime(<); } /* FIXME */ if (addms) { struct timeval tv; dstr contract = dstr_new(quote->thyquote.m_cHYDM); struct sms *sms; gettimeofday(&tv, NULL); if ((sms = table_get_value(times, contract)) == NULL) { if (NEW(sms)) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; table_insert(times, contract, sms); } } else if (sms->qsec != quote->thyquote.m_nTime) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; dstr_free(contract); } else { int32_t offset; if ((offset = (tv.tv_sec - sms->sec) * 1000 + tv.tv_usec / 1000 - sms->msec) > 999) offset = 999; quote->m_nMSec = offset; dstr_free(contract); } } } if (NEW0(msg) == NULL) { FREE(buf); return; } msg->data = buf; msg->refcount = 1; thrpool_queue(tp, send_quote, msg, NULL, msgfree, NULL); } else FREE(buf); }