Пример #1
0
/* FIXME */
void sall_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;
		struct kvd *kvd;

		table_rwlock_wrlock(subscribers);
		if ((dlist = table_get_value(subscribers, pkey)) == NULL) {
			if (NEW(kvd)) {
				kvd->key = skey;
				kvd->u.dlist = dlist_new(NULL, NULL);
				dlist_insert_tail(kvd->u.dlist, c);
				dlist = dlist_new(cmpkvd, kdfree);
				dlist_insert_sort(dlist, kvd);
				table_insert(subscribers, pkey, dlist);
			} else {
				add_reply_error(c, "error allocating memory for kvd\r\n");
				dstr_free(skey);
				dstr_free(pkey);
			}
		} else {
			if (NEW(kvd)) {
				dlist_node_t node;

				kvd->key     = skey;
				kvd->u.dlist = dlist_new(NULL, NULL);
				if ((node = dlist_find(dlist, kvd)) == NULL) {
					dlist_insert_tail(kvd->u.dlist, c);
					dlist_insert_sort(dlist, kvd);
				} else {
					kdfree(kvd);
					kvd = (struct kvd *)dlist_node_value(node);
					if (dlist_find(kvd->u.dlist, c) == NULL)
						dlist_insert_tail(kvd->u.dlist, c);
				}
			} else {
				add_reply_error(c, "error allocating memory for kvd\r\n");
				dstr_free(skey);
			}
			dstr_free(pkey);
		}
		table_rwlock_unlock(subscribers);
	}
	dstr_free(res);
//--------------------------------------------------------------------------------------------------------------------
//	FIXME
//--------------------------------------------------------------------------------------------------------------------
}
Пример #2
0
/****************************************************************
*  Constructor
*/
void *strstr_new(t_symbol *sym, long argc, t_atom *argv)
{
  t_strstr *x = NULL;

  x = (t_strstr *)object_alloc(strstr_class);

  if (x == NULL) {
    error("strstr:  Allocation failed.");
    return NULL;
  }

  // Set inlets, outlets, and proxy
  x->inl_proxy_ind = 0;
  x->inl_proxy = proxy_new((t_object *)x, 1, &x->inl_proxy_ind);
  x->outl_int = intout((t_object *)x);

  // Set the left string buffer
  x->i_dstr1 = dstr_new();

  // First argument:  right string buffer
  x->i_dstr2 = dstr_new();
  if ((argc >= 1) && (attr_args_offset((short)argc, argv) >= 1)) {
    x->i_dstr2 = str_cat_atom(x, x->i_dstr2, argv);
  }

  // Test the string buffers
  if (DSTR_IS_NULL(x->i_dstr1) || DSTR_IS_NULL(x->i_dstr2)) {
    object_error((t_object *)x, "Allocation error.");
    strstr_free(x);
    return NULL;
  }

  // Second argument:  mode
  long mode = 0;
  if ((argc >= 2) && (attr_args_offset((short)argc, argv) >= 2)) {
    if ((atom_gettype(argv + 1) == A_LONG) && (atom_getlong(argv + 1) >= 0) && (atom_getlong(argv + 1) <= 1)) {
      mode = (long)atom_getlong(argv + 1);
    } else {
      object_error((t_object *)x, "Arg 2:  Mode:  0 or 1 expected");
    }
  }
  object_attr_setlong(x, gensym("mode"), mode);

  // Set the float precision
  object_attr_setlong(x, gensym("fprecision"), 6);

  // Set the remaining variables
  x->o_pos = -1;

  // Process the attributes
  attr_args_process(x, (short)argc, argv);

  return x;
}
Пример #3
0
/* 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);
}
Пример #4
0
/* FIXME */
int xcb_query(xcb_context_t c, const char *sid, const char *index, const char *pattern,
	struct tm *start, struct tm *end) {
	dstr s;
	char buf[128];

	if (sid == NULL || index == NULL || start == NULL || end == NULL) {
		xcb_set_error(c, XCB_ERR_OTHER, "Session ID, index, start or end can't be empty");
		return XCB_ERR;
	}
	s = dstr_new("Q");
	s = dstr_cat(s, index);
	s = dstr_cat(s, ",");
	s = dstr_cat(s, sid);
	s = dstr_cat(s, ",");
	if (pattern)
		s = dstr_cat(s, pattern);
	s = dstr_cat(s, ",");
	strftime(buf, sizeof buf, "%F %T", start);
	s = dstr_cat(s, buf);
	s = dstr_cat(s, ",");
	strftime(buf, sizeof buf, "%F %T", end);
	s = dstr_cat(s, buf);
	s = dstr_cat(s, "\r\n");
	if (net_try_write(c->fd, s, dstr_length(s), 10, NET_NONBLOCK) == -1) {
		xcb_set_error(c, XCB_ERR_IO, NULL);
		dstr_free(s);
		return XCB_ERR;
	}
	dstr_free(s);
	return XCB_OK;
}
Пример #5
0
static void tcp_accept_handler(event_loop el, int fd, int mask, void *data) {
	char cip[128];
	int cport, cfd;
	client c;
	NOT_USED(el);
	NOT_USED(mask);
	NOT_USED(data);

	if ((cfd = net_tcp_accept(fd, cip, &cport, neterr, sizeof neterr)) == -1) {
		xcb_log(XCB_LOG_WARNING, "Accepting client connection: %s", neterr);
		return;
	}
	if ((c = client_new(cfd, fd)) == NULL) {
		xcb_log(XCB_LOG_WARNING, "Error registering fd '%d' event for the new client: %s",
			cfd, strerror(errno));
		close(cfd);
	} else {
		/* heartbeat */
		dstr res = dstr_new("HEARTBEAT|");
		dstr ip = getipv4();

		xcb_log(XCB_LOG_NOTICE, "Accepted %s:%d, client '%p'", cip, cport, c);
		res = dstr_cat(res, ip);
		res = dstr_cat(res, "\r\n");
		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);
		dstr_free(ip);
		dstr_free(res);
	}
}
Пример #6
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);
}
Пример #7
0
/* FIXME */
xcb_context_t xcb_connect(const char *addr, int port) {
	xcb_context_t c = xcb_context_init();

	if (c == NULL)
		goto end;
	if (xcb_connect_tcp(c, addr, port) == XCB_ERR)
		goto end;
	info.c    = c;
	info.ip   = dstr_new(addr);
	info.port = port;
	if (pthread_create(&cthread, NULL, check_thread, &info) != 0)
		xcb_set_error_from_errno(c, XCB_ERR_OTHER, "pthread_create");

end:
	return c;
}
Пример #8
0
/* FIXME */
int xcb_indices(xcb_context_t c, const char *sid) {
	dstr s;

	if (sid == NULL) {
		xcb_set_error(c, XCB_ERR_OTHER, "Session ID can't be empty");
		return XCB_ERR;
	}
	s = dstr_new("INDICES,");
	s = dstr_cat(s, sid);
	s = dstr_cat(s, "\r\n");
	if (net_try_write(c->fd, s, dstr_length(s), 10, NET_NONBLOCK) == -1) {
		xcb_set_error(c, XCB_ERR_IO, NULL);
		dstr_free(s);
		return XCB_ERR;
	}
	dstr_free(s);
	return XCB_OK;
}
Пример #9
0
/* FIXME */
int xcb_index(xcb_context_t c, const char *index) {
	dstr s;

	if (index == NULL) {
		xcb_set_error(c, XCB_ERR_OTHER, "Index can't be empty");
		return XCB_ERR;
	}
	s = dstr_new("INDEX,");
	s = dstr_cat(s, index);
	s = dstr_cat(s, "\r\n");
	if (net_try_write(c->fd, s, dstr_length(s), 10, NET_NONBLOCK) == -1) {
		xcb_set_error(c, XCB_ERR_IO, NULL);
		dstr_free(s);
		return XCB_ERR;
	}
	dstr_free(s);
	return XCB_OK;
}
Пример #10
0
/* FIXME */
void qc_command(client c) {
	char buf[64];
	dstr rid;
	struct crss *crss;

	snprintf(buf, sizeof buf, "%p,", c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, c->argv[1]);
	if (rids == NULL)
		rids = table_new(cmpstr, hashmurmur2, kfree, NULL);
	table_lock(rids);
	if ((crss = table_get_value(rids, rid))) {
		crss->cancel = 1;
		xcb_log(XCB_LOG_DEBUG, "Query with rid '%s' got cancelled", c->argv[1]);
	}
	table_unlock(rids);
	add_reply_string(c, "\r\n", 2);
	dstr_free(rid);
}
Пример #11
0
int main(int argc, char **argv) {
	int opt, count = 1;
	pthread_t thread;

	/* FIXME */
	ip = dstr_new("127.0.0.1");
	port = 33330;
	while ((opt = getopt(argc, argv, "h:p:xt?")) != -1)
		switch (opt) {
		case 'h':
			dstr_free(ip);
			ip = dstr_new(optarg);
			count += 2;
			break;
		case 'p':
			port = atoi(optarg);
			count += 2;
			break;
		case 'x':
			execute = 1;
			count += 1;
			break;
		case 't':
			timestamp = 1;
			count += 1;
			break;
		case '?':
		default:
			usage();
		}
	if ((tcpsock = net_tcp_nonblock_connect(ip, port, neterr, sizeof neterr)) == -1) {
		fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, neterr);
		exit(1);
	}
	if (errno == EINPROGRESS) {
		struct pollfd wfd[1];
		int res, err = 0;
		socklen_t errlen = sizeof err;

		wfd[0].fd     = tcpsock;
		wfd[0].events = POLLOUT;
		/* wait for 5 seconds */
		if ((res = poll(wfd, 1, 5000)) == -1) {
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		} else if (res == 0) {
			errno = ETIMEDOUT;
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
		if (getsockopt(tcpsock, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
		if (err) {
			errno = err;
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
	}
	if (execute && pipe(proceed_pipe) != 0) {
		fprintf(stderr, "Error creating pipe: %s\n", strerror(errno));
		exit(1);
	}
	if (execute) {
		argc -= count;
		argv += count;
		if (argc > 0) {
			dstr cmd;
			int i;
			struct pollfd rfd[1];

			if (pthread_create(&thread, NULL, recv_thread, NULL) != 0) {
				fprintf(stderr, "Error initializing receiver thread\n");
				exit(1);
			}
			cmd = dstr_new(argv[0]);
			for (i = 1; i < argc; ++i) {
				cmd = dstr_cat(cmd, " ");
				cmd = dstr_cat(cmd, argv[i]);
			}
			cmd = dstr_cat(cmd, "\r\n");
			net_try_write(tcpsock, cmd, dstr_length(cmd), 100, NET_NONBLOCK);
			/* dstr_free(cmd); */
			rfd[0].fd     = proceed_pipe[0];
			rfd[0].events = POLLIN;
			if (poll(rfd, 1, -1) == -1) {
				fprintf(stderr, "Error polling: %s\n", strerror(errno));
				exit(1);
			}
		}
	} else {
		fprintf(stdout, "XCUBE CLI, Copyright (c) 2013-2015, "
			"Dalian Futures Information Technology Co., Ltd.\n");
		fprintf(stdout, "Type 'help' or '?' for help.\n");
		init_readline();
		stifle_history(100);
		if (pthread_create(&thread, NULL, recv_thread, NULL) != 0) {
			fprintf(stderr, "Error initializing receiver thread\n");
			exit(1);
		}
		while (loop) {
			char *line;

			line = readline(prompt);
			if (rl_inited == 0)
				rl_inited = 1;
			if (line == NULL)
				continue;
			LTRIM(line);
			RTRIM(line);
			if (*line) {
				add_history(line);
				if (tcpsock == -1)
					execute_line(line);
				else {
					net_try_write(tcpsock, line, strlen(line), 100, NET_NONBLOCK);
					net_try_write(tcpsock, "\r\n", 2, 100, NET_NONBLOCK);
					if (!strncasecmp(line, "quit", 4))
						com_quit(NULL);
				}
			}
			FREE(line);
		}
	}
	return 0;
}
Пример #12
0
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;
}
Пример #13
0
static int vxo_exec(void *data, void *data2) {
	RAII_VAR(struct msg *, msg, (struct msg *)data, msg_decr);
	struct msgs *out = (struct msgs *)data2;
	dstr *fields = NULL;
	int nfield = 0;
	double vol, vol2, vol3, spot, strike, r, expiry;
	int sec, msec;
	dstr spotname;
	char *type;
	struct pd *pd;
	struct scp *scp;

	fields = dstr_split_len(msg->data, strlen(msg->data), ",", 1, &nfield);
	/* FIXME */
	if (nfield != 19) {
		xcb_log(XCB_LOG_WARNING, "Message '%s' garbled", msg->data);
		goto end;
	}
	vol      = !strcasecmp(fields[5], "nan") ? NAN : atof(fields[5]);
	vol2     = !strcasecmp(fields[7], "nan") ? NAN : atof(fields[7]);
	vol3     = !strcasecmp(fields[9], "nan") ? NAN : atof(fields[9]);
	if (isnan(vol) && isnan(vol2) && isnan(vol3))
		goto end;
	sec      = atoi(fields[1]);
	msec     = atoi(fields[2]);
	spot     = atof(fields[10]);
	spotname = dstr_new(fields[11]);
	type     = fields[12];
	strike   = atof(fields[13]);
	r        = atof(fields[14]);
	expiry   = atof(fields[15]);
	table_lock(spots);
	if ((pd = table_get_value(spots, spotname)) == NULL) {
		/* can't happen */
		if (NEW(scp) == NULL) {
			xcb_log(XCB_LOG_WARNING, "Error allocating memory for scp");
			table_unlock(spots);
			goto end;
		}
		scp->strike = strike;
		if (!strcasecmp(type, "C")) {
			scp->cvol  = vol;
			scp->pvol  = NAN;
			scp->cvol2 = vol2;
			scp->pvol2 = NAN;
			scp->cvol3 = vol3;
			scp->pvol3 = NAN;
		} else {
			scp->cvol  = NAN;
			scp->pvol  = vol;
			scp->cvol2 = NAN;
			scp->pvol2 = vol2;
			scp->cvol3 = NAN;
			scp->pvol3 = vol3;
		}
		if (NEW(pd) == NULL) {
			xcb_log(XCB_LOG_WARNING, "Error allocating memory for pd");
			FREE(scp);
			table_unlock(spots);
			goto end;
		}
		pd->prevxo = pd->prevxo2 = pd->prevxo3 = NAN;
		pd->sep    = strchr(fields[3], '-') ? "-" : "";
		pd->dlist  = dlist_new(NULL, scpfree);
		dlist_insert_tail(pd->dlist, scp);
		table_insert(spots, spotname, pd);
	} else {
		dlist_iter_t iter = dlist_iter_new(pd->dlist, DLIST_START_HEAD);
		dlist_node_t node;

		while ((node = dlist_next(iter))) {
			scp = (struct scp *)dlist_node_value(node);
			if (scp->strike > strike || fabs(scp->strike - strike) <= 0.000001)
				break;
		}
		if (node && fabs(scp->strike - strike) <= 0.000001) {
			if (!strcasecmp(type, "C")) {
				scp->cvol  = vol;
				scp->cvol2 = vol2;
				scp->cvol3 = vol3;
			} else {
				scp->pvol  = vol;
				scp->pvol2 = vol2;
				scp->pvol3 = vol3;
			}
		} else {
			/* can't happen */
			if (NEW(scp) == NULL) {
				xcb_log(XCB_LOG_WARNING, "Error allocating memory for scp");
				table_unlock(spots);
				goto end;
			}
			scp->strike = strike;
			if (!strcasecmp(type, "C")) {
				scp->cvol  = vol;
				scp->pvol  = NAN;
				scp->cvol2 = vol2;
				scp->pvol2 = NAN;
				scp->cvol3 = vol3;
				scp->pvol3 = NAN;
			} else {
				scp->cvol  = NAN;
				scp->pvol  = vol;
				scp->cvol2 = NAN;
				scp->pvol2 = vol2;
				scp->cvol3 = NAN;
				scp->pvol3 = vol3;
			}
			if (node == NULL)
				dlist_insert_tail(pd->dlist, scp);
			else
				dlist_insert(pd->dlist, node, scp, 0);
		}
		dlist_iter_rewind_head(iter, pd->dlist);
		while ((node = dlist_next(iter))) {
			scp = (struct scp *)dlist_node_value(node);
			if (scp->strike > spot || fabs(scp->strike - spot) <= 0.000001)
				break;
		}
		dlist_iter_free(&iter);
		if (node && dlist_node_prev(node)) {
			struct scp *scp1 = (struct scp *)dlist_node_value(node);
			struct scp *scp2 = (struct scp *)dlist_node_value(dlist_node_prev(node));
			double vxo = NAN, vxo2 = NAN, vxo3 = NAN;
			int flag1, flag2, flag3;

			if (!isnan(scp1->cvol) && !isnan(scp1->pvol) && !isnan(scp2->cvol) && !isnan(scp2->pvol))
				vxo  = ((scp1->cvol + scp1->pvol) / 2) *
					(spot - scp2->strike) / (scp1->strike - scp2->strike) +
					((scp2->cvol + scp2->pvol) / 2) *
					(scp1->strike - spot) / (scp1->strike - scp2->strike);
			if (!isnan(scp1->cvol2) && !isnan(scp1->pvol2) && !isnan(scp2->cvol2) && !isnan(scp2->pvol2))
				vxo2 = ((scp1->cvol2 + scp1->pvol2) / 2) *
					(spot - scp2->strike) / (scp1->strike - scp2->strike) +
					((scp2->cvol2 + scp2->pvol2) / 2) *
					(scp1->strike - spot) / (scp1->strike - scp2->strike);
			if (!isnan(scp1->cvol3) && !isnan(scp1->pvol3) && !isnan(scp2->cvol3) && !isnan(scp2->pvol3))
				vxo3 = ((scp1->cvol3 + scp1->pvol3) / 2) *
					(spot - scp2->strike) / (scp1->strike - scp2->strike) +
					((scp2->cvol3 + scp2->pvol3) / 2) *
					(scp1->strike - spot) / (scp1->strike - scp2->strike);
			if ((flag1 = (isnan(pd->prevxo) && !isnan(vxo)) || (!isnan(pd->prevxo) && isnan(vxo)) ||
				(!isnan(pd->prevxo) && !isnan(vxo) && fabs(pd->prevxo - vxo) > 0.000001) ? 1 : 0))
				pd->prevxo  = vxo;
			if ((flag2 = (isnan(pd->prevxo2) && !isnan(vxo2)) || (!isnan(pd->prevxo2) && isnan(vxo2)) ||
				(!isnan(pd->prevxo2) && !isnan(vxo2) && fabs(pd->prevxo2 - vxo2) > 0.000001) ? 1 : 0))
				pd->prevxo2 = vxo2;
			if ((flag3 = (isnan(pd->prevxo3) && !isnan(vxo3)) || (!isnan(pd->prevxo3) && isnan(vxo3)) ||
				(!isnan(pd->prevxo3) && !isnan(vxo3) && fabs(pd->prevxo3 - vxo3) > 0.000001) ? 1 : 0))
				pd->prevxo3 = vxo3;
			if (flag1 || flag2 || flag3) {
				char *res;

				if ((res = ALLOC(4096))) {
					time_t t = (time_t)sec;
					struct tm lt;
					char datestr[64];
					int off;

					strftime(datestr, sizeof datestr, "%F %T", localtime_r(&t, &lt));
					snprintf(res, 4096, "VXO,%s.%03d,%s|%f,%f,%f",
						datestr,
						msec,
						spotname,
						vxo,
						vxo2,
						vxo3);
					out2rmp(res);
					off = snprintf(res, 4096, "VXO,%d,%d,%s,",
						sec,
						msec,
						spotname);
					iter = dlist_iter_new(pd->dlist, DLIST_START_HEAD);
					while ((node = dlist_next(iter))) {
						scp = (struct scp *)dlist_node_value(node);
						off += snprintf(res + off, 4096 - off, "%.f,%f,%f,%f,",
							scp->strike,
							vxo,
							vxo2,
							vxo3);
					}
					dlist_iter_free(&iter);
					snprintf(res + off, 4096 - off, "%.2f,%f,%f,%s",
						spot,
						r,
						expiry,
						pd->sep);
					if (out2msgs(res, out) == -1)
						FREE(res);
				}
			}
		}
		dstr_free(spotname);
	}
	table_unlock(spots);

end:
	dstr_free_tokens(fields, nfield);
	return 0;
}
Пример #14
0
/* FIXME */
void s_command(client c) {
	dstr pkey, skey;
	int i;
	dlist_t dlist;
	struct kvd *kvd;

	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);
//------------------------------------------------------------------------
dstr pre = dstr_new(pkey);
dstr rest = dstr_new("");
//------------------------------------------------------------------------
	if (c->argc > 1)
		for (i = 1; i < c->argc; ++i) {
			skey = dstr_cat(skey, ",");
			skey = dstr_cat(skey, c->argv[i]);
//------------------------------------------------------------------------
			rest = dstr_cat(rest,c->argv[i]);
//------------------------------------------------------------------------
		}
/*
	table_lock(cache);
	if ((dlist = table_get_value(cache, pkey))) {
		dlist_iter_t iter = dlist_iter_new(dlist, DLIST_START_HEAD);
		dlist_node_t node;
*/
		/* FIXME: still has room to improve */
/*		while ((node = dlist_next(iter))) {
			kvd = (struct kvd *)dlist_node_value(node);
			if (dstr_length(kvd->key) >= dstr_length(skey) &&
				!memcmp(kvd->key, skey, dstr_length(skey))) {
				dstr *fields = NULL;
				int nfield = 0;
				dstr res, contracts = NULL;

				fields = dstr_split_len(kvd->key, dstr_length(kvd->key), ",", 1, &nfield);
				res = dstr_new(fields[0]);
				if (nfield > 1) {
					contracts = dstr_new(fields[1]);
					for (i = 2; i < nfield; ++i) {
						contracts = dstr_cat(contracts, ",");
						contracts = dstr_cat(contracts, fields[i]);
					}
				}
				dstr_free_tokens(fields, nfield);
				fields = NULL, nfield = 0;
				fields = dstr_split_len(kvd->u.value, dstr_length(kvd->u.value),
					",", 1, &nfield);
				res = dstr_cat(res, ",");
				res = dstr_cat(res, fields[0]);
				if (contracts) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, contracts);
				}
				for (i = 1; i < nfield; ++i) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, fields[i]);
				}
				res = dstr_cat(res, "\r\n");
				pthread_spin_lock(&c->lock);
				if (!(c->flags & CLIENT_CLOSE_ASAP)) {
					if (net_try_write(c->fd, res, dstr_length(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);
							pthread_spin_unlock(&c->lock);
							dstr_free(contracts);
							dstr_free(res);
							dstr_free_tokens(fields, nfield);
							table_unlock(cache);
							dstr_free(skey);
							dstr_free(pkey);
							return;
						}
					} else if (c->eagcount)
						c->eagcount = 0;
				}
				pthread_spin_unlock(&c->lock);
				dstr_free(contracts);
				dstr_free(res);
				dstr_free_tokens(fields, nfield);
			}
		}
		dlist_iter_free(&iter);
	}
	table_unlock(cache);
*/
//---------------------------------------------------------------------------------------------------
/*	table_rwlock_wrlock(subscribers);
	if ((dlist = table_get_value(subscribers, pkey)) == NULL) {
		if (NEW(kvd)) {
			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			dlist_insert_tail(kvd->u.dlist, c);
			dlist = dlist_new(cmpkvd, kdfree);
			dlist_insert_sort(dlist, kvd);
			table_insert(subscribers, pkey, dlist);
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
			dstr_free(pkey);
		}
	} else {
		if (NEW(kvd)) {
			dlist_node_t node;

			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			if ((node = dlist_find(dlist, kvd)) == NULL) {
				dlist_insert_tail(kvd->u.dlist, c);
				dlist_insert_sort(dlist, kvd);
			} else {
				kdfree(kvd);
				kvd = (struct kvd *)dlist_node_value(node);
				if (dlist_find(kvd->u.dlist, c) == NULL)
					dlist_insert_tail(kvd->u.dlist, c);
			}
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
		}
		dstr_free(pkey);
	}
	table_rwlock_unlock(subscribers);
*/
//--------------------------------------------------------------------------------------------------------------------
//	table_rwlock_wrlock(subscribers_radix);
	radix_block_insert(pre, ",", subscribers_radix->head);
	radix_insert(rest, radix_match(pre, subscribers_radix->head, subscribers_radix->head));
	pre = dstr_cat(pre,rest);
	insert_value(pre, c, subscribers_radix->head);
	dstr_free(pre);
	dstr_free(rest);

//	table_rwlock_unlock(subscribers_radix);
//---------------------------------------------------------------------------------------------------
}
Пример #15
0
/* FIXME */
void q_command(client c) {
	struct tm tm;
	char *end;
	char buf[64];
	dstr rid;
	struct crss *crss;

	if (!persistence) {
		add_reply_error(c, "database not open\r\n");
		return;
	}
	if (dstr_length(c->argv[0]) == 1) {
		add_reply_error(c, "index can't be empty\r\n");
		return;
	}
	if ((end = strptime(c->argv[3], "%F %T", &tm)) && *end == '\0')
		c->argv[3] = dstr_cat(c->argv[3], ".000");
	else if ((end = strptime(c->argv[3], "%F %R", &tm)) && *end == '\0')
		c->argv[3] = dstr_cat(c->argv[3], ":00.000");
	else {
		add_reply_error(c, "invalid time format, "
			"please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n");
		return;
	}
	if ((end = strptime(c->argv[4], "%F %T", &tm)) && *end == '\0')
		c->argv[4] = dstr_cat(c->argv[4], ".999");
	else if ((end = strptime(c->argv[4], "%F %R", &tm)) && *end == '\0')
		c->argv[4] = dstr_cat(c->argv[4], ":59.999");
	else {
		add_reply_error(c, "invalid time format, "
			"please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n");
		return;
	}
	snprintf(buf, sizeof buf, "%p,", c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, c->argv[1]);
	if (rids == NULL)
		rids = table_new(cmpstr, hashmurmur2, kfree, NULL);
	table_lock(rids);
	if ((crss = table_get_value(rids, rid))) {
		add_reply_error_format(c, "query with rid '%s' already exists\r\n", c->argv[1]);
		dstr_free(rid);
	} else if (NEW(crss)) {
		pthread_t thread;

		crss->c      = c;
		crss->rid    = dstr_new(c->argv[1]);
		crss->match  = dstr_new(c->argv[2]);
		crss->start  = dstr_new(c->argv[0] + 1);
		crss->start  = dstr_cat(crss->start, ",");
		crss->start  = dstr_cat(crss->start, c->argv[3]);
		crss->stop   = dstr_new(c->argv[0] + 1);
		crss->stop   = dstr_cat(crss->stop, ",");
		crss->stop   = dstr_cat(crss->stop, c->argv[4]);
		crss->cancel = 0;
		if (pthread_create(&thread, NULL, q_thread, crss) != 0) {
			add_reply_error(c, strerror(errno));
			add_reply_string(c, "\r\n", 2);
			dstr_free(crss->rid);
			dstr_free(crss->match);
			dstr_free(crss->start);
			dstr_free(crss->stop);
			FREE(crss);
			dstr_free(rid);
		} else {
			client_incr(crss->c);
			table_insert(rids, rid, crss);
		}
	} else {
		add_reply_error(c, "error allocating memory for crss\r\n");
		dstr_free(rid);
	}
	table_unlock(rids);
}
Пример #16
0
/* FIXME */
static void *q_thread(void *data) {
	struct crss *crss = (struct crss *)data;
	char buf[64];
	dstr rid, res = NULL;
	db_iterator_t *it;
	const char *key, *value;
	size_t klen, vlen;

	snprintf(buf, sizeof buf, "%p,", crss->c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, crss->rid);
	it = db_iterator_create(db, db_ro);
	db_iterator_seek(it, crss->start, dstr_length(crss->start));
	/* seek failed */
	if (!db_iterator_valid(it)) {
		res = dstr_new(crss->rid);
		res = dstr_cat(res, ",1\r\n\r\n");
		pthread_spin_lock(&crss->c->lock);
		if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
			xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
		pthread_spin_unlock(&crss->c->lock);
		goto end;
	}
	key = db_iterator_key(it, &klen);
	while (memcmp(key, crss->stop, dstr_length(crss->stop)) <= 0) {
		if (crss->cancel)
			break;
		if (!strcmp(crss->match, "") || strstr(key, crss->match)) {
			value = db_iterator_value(it, &vlen);
			res = dstr_new(crss->rid);
			res = dstr_cat(res, ",0,");
			res = dstr_cat_len(res, key, klen);
			res = dstr_cat(res, ",");
			res = dstr_cat_len(res, value, vlen);
			res = dstr_cat(res, "\r\n");
			pthread_spin_lock(&crss->c->lock);
			if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1) {
				xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
					crss->c, strerror(errno));
				pthread_spin_unlock(&crss->c->lock);
				goto end;
			}
			pthread_spin_unlock(&crss->c->lock);
			dstr_free(res);
		}
		db_iterator_next(it);
		if (!db_iterator_valid(it) || crss->cancel)
			break;
		key = db_iterator_key(it, &klen);
	}
	res = dstr_new(crss->rid);
	res = dstr_cat(res, ",1\r\n\r\n");
	pthread_spin_lock(&crss->c->lock);
	if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
		xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
	pthread_spin_unlock(&crss->c->lock);

end:
	db_iterator_destroy(&it);
	dstr_free(res);
	table_lock(rids);
	table_remove(rids, rid);
	table_unlock(rids);
	dstr_free(rid);
	client_decr(crss->c);
	dstr_free(crss->rid);
	dstr_free(crss->match);
	dstr_free(crss->start);
	dstr_free(crss->stop);
	FREE(crss);
	return NULL;
}
Пример #17
0
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, &lt);
			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(&lt);
		}
		/* 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);
}
Пример #18
0
static int mm_impvbaw_exec(void *data, void *data2) {
	RAII_VAR(struct msg *, msg, (struct msg *)data, msg_decr);
	dstr *fields = NULL;
	int nfield = 0;
	time_t t;
	dstr spotname;
	double vol;
	NOT_USED(data2);

	fields = dstr_split_len(msg->data, strlen(msg->data), ",", 1, &nfield);
	/* FIXME */
	if (nfield != 19) {
		xcb_log(XCB_LOG_WARNING, "Message '%s' garbled", msg->data);
		goto end;
	}
	t        = (time_t)atoi(fields[1]);
	spotname = dstr_new(fields[11]);
	vol      = atof(fields[5]);
	if (!isnan(vol)) {
		struct mm *mm;
		int flag = 0;

		table_lock(contracts);
		if ((mm = table_get_value(contracts, spotname)) == NULL) {
			if (NEW(mm)) {
				mm->min = mm->max = vol;
				flag = 1;
				table_insert(contracts, spotname, mm);
			} else
				xcb_log(XCB_LOG_WARNING, "Error allocating memory for mm");
		} else {
			if (mm->min > vol) {
				mm->min = vol;
				flag = 1;
			} else if (mm->max < vol) {
				mm->max = vol;
				flag = 1;
			}
			dstr_free(spotname);
		}
		if (mm && flag) {
			struct tm lt;
			char datestr[64], res[512];

			localtime_r(&t, &lt);
			lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
			strftime(datestr, sizeof datestr, "%F %T", &lt);
			snprintf(res, sizeof res, "MM_IMPVBAW,%s.000,%s|%f,%f",
				datestr,
				fields[11],
				mm->min,
				mm->max);
			out2rmp(res);
		}
		table_unlock(contracts);
	}

end:
	dstr_free_tokens(fields, nfield);
	return 0;
}
Пример #19
0
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, &lt);
				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(&lt);
			}
			/* 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);
}
Пример #20
0
static int impvbaw_exec(void *data, void *data2) {
	RAII_VAR(struct msg *, msg, (struct msg *)data, msg_decr);
	Quote *quote = (Quote *)msg->data;
	struct msgs *out = (struct msgs *)data2;
	dstr contract;
	float last;
	char *p;
	table_node_t node;

	contract = dstr_new(quote->thyquote.m_cHYDM);
	if (!strcmp(contract, "") || (fabs(quote->thyquote.m_dZXJ) <= 0.000001 &&
		fabs(quote->thyquote.m_dMRJG1) <= 0.000001 &&
		fabs(quote->thyquote.m_dMCJG1) <= 0.000001)) {
		xcb_log(XCB_LOG_WARNING, "Invalid quote: '%d,%d,%s,%.2f,%.2f,%.2f'",
			quote->thyquote.m_nTime,
			quote->m_nMSec,
			contract,
			quote->thyquote.m_dZXJ,
			quote->thyquote.m_dMRJG1,
			quote->thyquote.m_dMCJG1);
		goto end;
	}
	/* FIXME */
	if (!strncasecmp(contract, "IO", 2) || !strncasecmp(contract, "HO", 2) ||
		!strncasecmp(contract, "00", 2) || !strncasecmp(contract, "60", 2))
		goto end;
	last = quote->thyquote.m_dZXJ;
	if ((p = strrchr(contract, 'C')) == NULL)
		p = strrchr(contract, 'P');
	/* FIXME: option quote */
	if (p && p != contract && p != contract + dstr_length(contract) - 1 &&
		((*(p - 1) == '-' && *(p + 1) == '-') || (isdigit(*(p - 1)) && isdigit(*(p + 1))))) {
		dstr spotname, type, strike;
		float spot;
		struct prices *prices;
		double expiry, vol, vol2, vol3;
		struct tm lt;
		char *res;

		spotname = *(p - 1) == '-' ? dstr_new_len(contract, p - contract - 1) :
			dstr_new_len(contract, p - contract);
		type     = dstr_new_len(p, 1);
		strike   = *(p + 1) == '-' ? dstr_new_len(p + 2, contract + dstr_length(contract) - p - 2) :
			dstr_new_len(p + 1, contract + dstr_length(contract) - p - 1);
		table_rwlock_rdlock(spots);
		if ((node = table_find(spots, spotname)) == NULL) {
			table_rwlock_unlock(spots);
			dstr_free(strike);
			dstr_free(type);
			dstr_free(spotname);
			goto end;
		}
		spot = table_node_float(node);
		table_rwlock_unlock(spots);
		if (fabs(spot) <= 0.000001) {
			xcb_log(XCB_LOG_WARNING, "The price of spot '%s' be zero", spotname);
			dstr_free(strike);
			dstr_free(type);
			dstr_free(spotname);
			goto end;
		}
		table_lock(optns);
		if ((node = table_find(optns, contract)) == NULL) {
			if (NEW(prices)) {
				prices->prelast = last;
				prices->prebid1 = quote->thyquote.m_dMRJG1;
				prices->preask1 = quote->thyquote.m_dMCJG1;
				prices->prespot = spot;
				table_insert(optns, dstr_new(contract), prices);
			} else
				xcb_log(XCB_LOG_WARNING, "Error allocating memory for prices");
		} else {
			prices = (struct prices *)table_node_value(node);

			if (fabs(prices->prelast - last) <= 0.000001 &&
				fabs(prices->prebid1 - quote->thyquote.m_dMRJG1) <= 0.000001 &&
				fabs(prices->preask1 - quote->thyquote.m_dMCJG1) <= 0.000001 &&
				fabs(prices->prespot - spot) <= 0.000001) {
				table_unlock(optns);
				dstr_free(strike);
				dstr_free(type);
				dstr_free(spotname);
				goto end;
			} else {
				prices->prelast = last;
				prices->prebid1 = quote->thyquote.m_dMRJG1;
				prices->preask1 = quote->thyquote.m_dMCJG1;
				prices->prespot = spot;
			}
		}
		table_unlock(optns);
		if ((node = table_find(expiries, contract)))
			expiry = table_node_double(node);
		else {
			char *month;
			struct timeval tv;
			int diff;

			xcb_log(XCB_LOG_WARNING, "No exact expiry date for '%s'", contract);
			month = spotname + dstr_length(spotname) - 2;
			gettimeofday(&tv, NULL);
			if ((diff = atoi(month) - localtime_r(&tv.tv_sec, &lt)->tm_mon - 1) < 0)
				diff += 12;
			if (diff == 0)
				diff = 1;
			expiry = diff / 12.0;
		}
		/* FIXME: last price */
		if (fabs(last) <= 0.000001)
			vol = NAN;
		else
			vol = impv_baw(spot, atof(strike), r, r, expiry, last,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		/* FIXME: bid price 1 */
		if (fabs(quote->thyquote.m_dMRJG1) <= 0.000001)
			vol2 = NAN;
		else if (fabs(quote->thyquote.m_dMRJG1 - last) <= 0.000001)
			vol2 = vol;
		else
			vol2 = impv_baw(spot, atof(strike), r, r, expiry, quote->thyquote.m_dMRJG1,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		/* FIXME: ask price 1 */
		if (fabs(quote->thyquote.m_dMCJG1) <= 0.000001)
			vol3 = NAN;
		else if (fabs(quote->thyquote.m_dMCJG1 - last) <= 0.000001)
			vol3 = vol;
		else
			vol3 = impv_baw(spot, atof(strike), r, r, expiry, quote->thyquote.m_dMCJG1,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		if ((res = ALLOC(512))) {
			time_t t = (time_t)quote->thyquote.m_nTime;
			char datestr[64];

			strftime(datestr, sizeof datestr, "%F %T", localtime_r(&t, &lt));
			snprintf(res, 512, "IMPVBAW,%s.%03d,%s|%.2f,%f,%.2f,%f,%.2f,%f,%.2f",
				datestr,
				quote->m_nMSec,
				contract,
				last,
				vol,
				quote->thyquote.m_dMRJG1,
				vol2,
				quote->thyquote.m_dMCJG1,
				vol3,
				spot);
			out2rmp(res);
			snprintf(res, 512, "IMPVBAW,%d,%d,%s,%.2f,%f,%.2f,%f,%.2f,%f,%.2f,%s,%s,%s,%f,%f,%d,0,0",
				quote->thyquote.m_nTime,
				quote->m_nMSec,
				contract,
				last,
				vol,
				quote->thyquote.m_dMRJG1,
				vol2,
				quote->thyquote.m_dMCJG1,
				vol3,
				spot,
				spotname,
				type,
				strike,
				r,
				expiry,
				quote->thyquote.m_nCJSL);
			if (out2msgs(res, out) == -1)
				FREE(res);
		} else
			xcb_log(XCB_LOG_WARNING, "Error allocating memory for result");
		dstr_free(strike);
		dstr_free(type);
		dstr_free(spotname);
	/* future quote */
	} else {
		table_rwlock_wrlock(spots);
		if ((node = table_find(spots, contract)) == NULL) {
			if ((node = table_insert_raw(spots, contract)))
				table_set_float(node, last);
		} else {
			table_set_float(node, last);
			dstr_free(contract);
		}
		table_rwlock_unlock(spots);
		return 0;
	}

end:
	dstr_free(contract);
	return 0;
}
Пример #21
0
int main(int argc, char **argv) {
	int opt, i = 1, fd, sock;
	struct stat sb;
	char *addr, *p, *q;
	char neterr[256];
	int pfd[2];

	/* FIXME */
	ip = dstr_new("127.0.0.1");
	port = 33330;
	while ((opt = getopt(argc, argv, "h:p:?")) != -1)
		switch (opt) {
		case 'h':
			dstr_free(ip);
			ip = dstr_new(optarg);
			i += 2;
			break;
		case 'p':
			port = atoi(optarg);
			i += 2;
			break;
		case '?':
		default:
			usage();
		}
	if ((fd = open(argv[i], O_RDONLY)) == -1) {
		fprintf(stderr, "Error opening file: %s\n", strerror(errno));
		exit(1);
	}
	fstat(fd, &sb);
	if ((addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
		fprintf(stderr, "Error mmaping file: %s\n", strerror(errno));
		exit(1);
	}
	close(fd);
	if ((sock = net_udp_nonblock_connect(ip, port, neterr, sizeof neterr)) == -1) {
		fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, neterr);
		exit(1);
	}
	if (pipe(pfd) != 0) {
		fprintf(stderr, "Error creating pipe: %s\n", strerror(errno));
		exit(1);
	}
	p = addr;
	q = memchr(p, '\n', sb.st_size);
	while (q) {
		int len = PAGEALIGN(q - p + 1);
		char *line;

		if ((line = POSIXALIGN(sysconf(_SC_PAGESIZE), len))) {
			struct iovec iov;

			memset(line, '\0', len);
			strncpy(line, p, q - p);
			iov.iov_base = line;
			iov.iov_len  = len;
			/* zero copy */
			if (vmsplice(pfd[1], &iov, 1, SPLICE_F_GIFT) == -1) {
				fprintf(stderr, "Error vmsplicing: %s\n", strerror(errno));
				exit(1);
			}

again:
			if (splice(pfd[0], NULL, sock, NULL, len, SPLICE_F_MOVE) == -1) {
				if (errno == EAGAIN)
					goto again;
				else {
					fprintf(stderr, "Error splicing: %s\n", strerror(errno));
					exit(1);
				}
			}
			FREE(line);
		} else
			fprintf(stderr, "Error allocating memory for line\n");
		p = q + 1;
		q = memchr(p, '\n', sb.st_size - (q - addr));
	}
	close(pfd[0]);
	close(pfd[1]);
	close(sock);
	munmap(addr, sb.st_size);
	return 0;
}
Пример #22
0
static void *recv_thread(void *data) {
	NOT_USED(data);

	while (loop) {
		struct pollfd rfd[1];
		char buf[256];
		int nread;

		rfd[0].fd     = tcpsock;
		rfd[0].events = POLLIN;
		if (poll(rfd, 1, -1) == -1) {
			if (execute) {
				fprintf(stderr, "Reading from server: %s\n", strerror(errno));
				exit(1);
			} else {
				snprintf(buf, sizeof buf, "Reading from server: %s", strerror(errno));
				CLIPRINT(buf);
				break;
			}
		}
		if ((nread = read(tcpsock, inbuf + inpos, sizeof inbuf - inpos)) == -1) {
			if (errno == EAGAIN || errno == EINTR)
				nread = 0;
			else {
				if (execute) {
					fprintf(stderr, "Reading from server: %s\n", strerror(errno));
					exit(1);
				} else {
					snprintf(buf, sizeof buf, "Reading from server: %s", strerror(errno));
					CLIPRINT(buf);
					break;
				}
			}
		} else if (nread == 0) {
			if (execute) {
				fprintf(stderr, "Server closed connection\n");
				exit(1);
			} else {
				snprintf(buf, sizeof buf, "Server closed connection");
				CLIPRINT(buf);
				break;
			}
		}
		if (nread)
			inpos += nread;
		else
			continue;
		inbuf[inpos] = '\0';
		while (inpos > 0) {
			char *newline;
			size_t len;

			if ((newline = strstr(inbuf, "\r\n")) == NULL) {
				if (inpos == sizeof inbuf - 1) {
					if (execute) {
						fprintf(stderr, "Server error: too big reply\n");
						exit(1);
					} else {
						snprintf(buf, sizeof buf, "Server error: too big reply");
						CLIPRINT(buf);
						inpos = 0;
					}
				}
				break;
			}
			if ((len = newline - inbuf) == 0) {
				const char one = '1';

				if (execute && write(proceed_pipe[1], &one, sizeof(one)) == -1) {
					fprintf(stderr, "Error writing: %s", strerror(errno));
					exit(1);
				}
			} else {
				/* FIXME */
				*newline = '\0';
				if (timestamp) {
					struct timeval tv;
					char datestr[64];
					int off;
					dstr res;

					gettimeofday(&tv, NULL);
					off = strftime(datestr, sizeof datestr, "[%b %e %T.",
						localtime(&tv.tv_sec));
					snprintf(datestr + off, sizeof datestr - off, "%06d]",
						(int)tv.tv_usec);
					res = dstr_new(datestr);
					res = dstr_cat(res, inbuf);
					if (execute) {
						if (strncasecmp(inbuf, "HEARTBEAT", 9) &&
							strncasecmp(inbuf, "INDICES", 7))
							fprintf(stdout, "%s\n", res);
					} else
						CLIPRINT(res);
					dstr_free(res);
				} else {
					if (execute) {
						if (strncasecmp(inbuf, "HEARTBEAT", 9) &&
							strncasecmp(inbuf, "INDICES", 7))
							fprintf(stdout, "%s\n", inbuf);
					} else
						CLIPRINT(inbuf);
				}
			}
			memmove(inbuf, inbuf + len + 2, sizeof inbuf - len - 2);
			inpos -= len + 2;
		}
	}
	close(tcpsock);
	tcpsock = -1;
	return NULL;
}