Commit 9feb8a89 authored by Justin Mitchell's avatar Justin Mitchell
Browse files

Fix replay when the ringbuffer gets full and loops

parent be9a9c8f
Loading
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -116,38 +116,46 @@ void replay(ipc_connection_t *conn, ipc_message_t *msg)
	json_t *cmd = json_init(msg);

	/* find a pointer to the start/oldest item in store */
	int idx = store_wrap( store_next - store_len );
	int oldest = store_wrap( store_next - store_len );
	int len = store_len;

	/* which type did they say */
	if (json_object_get(cmd, "serial")!=NULL) {
		/* everything after serial # */
		uint64_t want = json_getint(cmd, "serial");
		for (int i=idx;i!=store_next;i=store_wrap(i+1)) {
			if ( store[i] == NULL) continue;
			if ( store[i]->head.serial >= want) {
				idx = i;
		int skip = 0;
		for (int i=0;i<len;i++) {
			int idx = store_wrap(oldest+i);
			if ( store[idx] == NULL) continue;
			if ( store[idx]->head.serial >= want)
				break;
			skip++;
		}
		}
		oldest = store_wrap( oldest + skip );
		len -= skip;
		/* if it fails, you get everything
		 * as it maybe got reset whilst you were away */
	}else
	if (json_object_get(cmd, "since")!=NULL) {
		/* everything after {unixtime} */
		int64_t want = json_getint(cmd, "since");
		while (idx != store_next) {
		int skip = 0;
		while (oldest != store_next) {
			/* list will be in date order */
			if (store[idx]!=NULL &&
				store[idx]->head.when >= want) break;
			idx = store_wrap(idx+1);
			if (store[oldest]!=NULL &&
				store[oldest]->head.when >= want) break;
			skip++;
		}
		oldest = store_wrap( oldest + skip );
		len -= skip;
		/* if it fails you get nothing as there is
		 * nothing newer (larger) than the date you gave */
	}else
	if (json_object_get(cmd, "count")!=NULL) {
		int want = json_getint(cmd, "count");
		if (want > store_len) want = store_len;
		idx = store_wrap( store_next - want );
		oldest = store_wrap( store_next - want );
		len = want;
	} else {
		json_decref(cmd);
		send_error(conn, msg, "Invalid replay command");
@@ -165,7 +173,8 @@ void replay(ipc_connection_t *conn, ipc_message_t *msg)
	LoadRoom(&user.room, user.record.room);

	/* now, go and replay those messages that are appropriate */
	for (;idx != store_next; idx = store_wrap( idx + 1 )) {
	for (int i=0; i<len; i++) {
		int idx = store_wrap( oldest + i );
		if (store[idx] == NULL) continue;

		/* this will be a subset of what you see in process_msg() */