[Spice-devel] [PATCH] replay: better record encapsulation
Frediano Ziglio
fziglio at redhat.com
Fri Dec 11 07:49:25 PST 2015
Remove global/static from red_record_qxl.c.
Defined a structure and use it to hold record state.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/red-record-qxl.c | 45 ++++++++++++++++++++++++++++++++++++++-------
server/red-record-qxl.h | 24 +++++++++++++++++++++---
server/red-worker.c | 28 ++++++++--------------------
3 files changed, 67 insertions(+), 30 deletions(-)
diff --git a/server/red-record-qxl.c b/server/red-record-qxl.c
index 0b966f0..cda6500 100644
--- a/server/red-record-qxl.c
+++ b/server/red-record-qxl.c
@@ -26,6 +26,7 @@
#include "memslot.h"
#include "red-parse-qxl.h"
#include "zlib-encoder.h"
+#include "red-record-qxl.h"
#if 0
static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
@@ -782,9 +783,11 @@ void red_record_cursor_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id,
}
}
-void red_record_dev_input_primary_surface_create(FILE *fd,
+void red_record_dev_input_primary_surface_create(SpiceRecord *record,
QXLDevSurfaceCreate* surface, uint8_t *line_0)
{
+ FILE *fd = record->fd;
+
fprintf(fd, "%d %d %d %d\n", surface->width, surface->height,
surface->stride, surface->format);
fprintf(fd, "%d %d %d %d\n", surface->position, surface->mouse_mode,
@@ -793,22 +796,22 @@ void red_record_dev_input_primary_surface_create(FILE *fd,
line_0);
}
-void red_record_event(FILE *fd, int what, uint32_t type, unsigned long ts)
+void red_record_event(SpiceRecord *record, int what, uint32_t type, unsigned long ts)
{
- static int counter = 0;
-
// TODO: record the size of the packet in the header. This would make
// navigating it much faster (well, I can add an index while I'm at it..)
// and make it trivial to get a histogram from a file.
// But to implement that I would need some temporary buffer for each event.
// (that can be up to VGA_FRAMEBUFFER large)
- fprintf(fd, "event %d %d %u %lu\n", counter++, what, type, ts);
+ fprintf(record->fd, "event %u %d %u %lu\n", record->counter++, what, type, ts);
}
-void red_record_qxl_command(FILE *fd, RedMemSlotInfo *slots,
+void red_record_qxl_command(SpiceRecord *record, RedMemSlotInfo *slots,
QXLCommandExt ext_cmd, unsigned long ts)
{
- red_record_event(fd, 0, ext_cmd.cmd.type, ts);
+ FILE *fd = record->fd;
+
+ red_record_event(record, 0, ext_cmd.cmd.type, ts);
switch (ext_cmd.cmd.type) {
case QXL_CMD_DRAW:
@@ -825,3 +828,31 @@ void red_record_qxl_command(FILE *fd, RedMemSlotInfo *slots,
break;
}
}
+
+bool red_record_open(SpiceRecord *record)
+{
+ static const char header[] = "SPICE_REPLAY 1\n";
+
+ const char *filename;
+ FILE *f;
+
+ filename = getenv("SPICE_WORKER_RECORD_FILENAME");
+ if (!filename)
+ return false;
+
+ f = fopen(filename, "w+");
+ if (!f)
+ goto error;
+
+ if (fwrite(header, sizeof(header)-1, 1, f) != 1) {
+ spice_error("failed to write replay header");
+ }
+
+ record->fd = f;
+ record->counter = 0;
+ return true;
+
+error:
+ spice_error("failed to open recording file %s\n", filename);
+ return false;
+}
diff --git a/server/red-record-qxl.h b/server/red-record-qxl.h
index 21f0bc9..2c8d8dd 100644
--- a/server/red-record-qxl.h
+++ b/server/red-record-qxl.h
@@ -23,12 +23,30 @@
#include "red-common.h"
#include "memslot.h"
+typedef struct SpiceRecord {
+ FILE *fd;
+ unsigned int counter;
+} SpiceRecord;
+
+bool red_record_open(SpiceRecord *record);
+
+static inline void red_record_close(SpiceRecord *record)
+{
+ fclose(record->fd);
+ record->fd = NULL;
+}
+
+static inline bool red_record_opened(SpiceRecord *record)
+{
+ return record->fd != NULL;
+}
+
void red_record_dev_input_primary_surface_create(
- FILE *fd, QXLDevSurfaceCreate *surface, uint8_t *line_0);
+ SpiceRecord *record, QXLDevSurfaceCreate *surface, uint8_t *line_0);
-void red_record_event(FILE *fd, int what, uint32_t type, unsigned long ts);
+void red_record_event(SpiceRecord *record, int what, uint32_t type, unsigned long ts);
-void red_record_qxl_command(FILE *fd, RedMemSlotInfo *slots,
+void red_record_qxl_command(SpiceRecord *record, RedMemSlotInfo *slots,
QXLCommandExt ext_cmd, unsigned long ts);
#endif
diff --git a/server/red-worker.c b/server/red-worker.c
index 15e7d12..1f6163e 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -96,7 +96,7 @@ struct RedWorker {
int driver_cap_monitors_config;
- FILE *record_fd;
+ SpiceRecord record;
};
QXLInstance* red_worker_get_qxl(RedWorker *worker)
@@ -254,8 +254,8 @@ static int red_process_display(RedWorker *worker, uint32_t max_pipe_size, int *r
continue;
}
- if (worker->record_fd)
- red_record_qxl_command(worker->record_fd, &worker->mem_slots, ext_cmd,
+ if (red_record_opened(&worker->record))
+ red_record_qxl_command(&worker->record, &worker->mem_slots, ext_cmd,
stat_now(worker->clockid));
stat_inc_counter(worker->command_counter, 1);
@@ -849,8 +849,8 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
if (error) {
return;
}
- if (worker->record_fd) {
- red_record_dev_input_primary_surface_create(worker->record_fd,
+ if (red_record_opened(&worker->record)) {
+ red_record_dev_input_primary_surface_create(&worker->record,
&surface, line_0);
}
@@ -1348,7 +1348,7 @@ static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *
{
RedWorker *worker = opaque;
- red_record_event(worker->record_fd, 1, message_type, stat_now(worker->clockid));
+ red_record_event(&worker->record, 1, message_type, stat_now(worker->clockid));
}
static void register_callbacks(Dispatcher *dispatcher)
@@ -1540,31 +1540,19 @@ RedWorker* red_worker_new(QXLInstance *qxl, RedDispatcher *red_dispatcher)
RedWorker *worker;
Dispatcher *dispatcher;
int i;
- const char *record_filename;
qxl->st->qif->get_init_info(qxl, &init_info);
worker = spice_new0(RedWorker, 1);
- record_filename = getenv("SPICE_WORKER_RECORD_FILENAME");
- if (record_filename) {
- static const char header[] = "SPICE_REPLAY 1\n";
-
- worker->record_fd = fopen(record_filename, "w+");
- if (worker->record_fd == NULL) {
- spice_error("failed to open recording file %s\n", record_filename);
- }
- if (fwrite(header, sizeof(header)-1, 1, worker->record_fd) != 1) {
- spice_error("failed to write replay header");
- }
- }
+ red_record_open(&worker->record);
dispatcher = red_dispatcher_get_dispatcher(red_dispatcher);
dispatcher_set_opaque(dispatcher, worker);
worker->red_dispatcher = red_dispatcher;
worker->qxl = qxl;
register_callbacks(dispatcher);
- if (worker->record_fd) {
+ if (red_record_opened(&worker->record)) {
dispatcher_register_universal_handler(dispatcher, worker_dispatcher_record);
}
worker->image_compression = image_compression;
--
2.4.3
More information about the Spice-devel
mailing list