From b1b52cff3e3a0b4d76b3f028f13c4e0dea80ec92 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Sat, 14 Apr 2012 14:55:55 +0400 Subject: [PATCH] Add comments to log_io.m. --- core/log_io.m | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/core/log_io.m b/core/log_io.m index f283ed63ad..5740ef8d7c 100644 --- a/core/log_io.m +++ b/core/log_io.m @@ -795,7 +795,10 @@ error: return NULL; } -/* this little hole shouldn't be used too much */ +/** + * Read the WAL and invoke a callback on every record (used for --cat + * command line option). + */ int read_log(const char *filename, row_handler *xlog_handler, row_handler *snap_handler, void *state) @@ -1201,18 +1204,41 @@ recover_finalize(struct recovery_state *r) } } +/** + * A pthread_atfork() callback for the child. We fork + * to save a snapshot, and in the child the writer + * thread is not necessary and not present. Make sure + * that atexit() handlers do not try to stop the + * non-existent thread. + */ static void wal_writer_child() { recovery_state->writer = NULL; } +/** + * Today a WAL writer is started once at start of the + * server. Nevertheless, use pthread_once() to make + * sure we can start/stop the writer many times. + */ static void wal_writer_init_once() { pthread_atfork(NULL, NULL, wal_writer_child); } +/** + * A watcher callback which is invoked whenever there + * are requests in wal_writer->output. This callback is + * associated with an internal WAL writer watcher and is + * invoked in the front-end main event loop. + * + * ev_async, under the hood, is a simple pipe. The WAL + * writer thread writes to that pipe whenever it's done + * handling a pack of requests (look for ev_async_send() + * call in the writer thread loop). + */ static void wal_writer_schedule(ev_watcher *watcher, int event __attribute__((unused))) { @@ -1236,6 +1262,11 @@ wal_writer_schedule(ev_watcher *watcher, int event __attribute__((unused))) } } +/** + * Initialize WAL writer context. Even though it's a singleton, + * encapsulate the details just in case we may use + * more writers in the future. + */ static void wal_writer_init(struct wal_writer *writer) { @@ -1271,6 +1302,7 @@ wal_writer_init(struct wal_writer *writer) tt_pthread_once(&wal_writer_once, wal_writer_init_once); } +/** Destroy a WAL writer structure. */ static void wal_writer_destroy(struct wal_writer *writer) { @@ -1314,6 +1346,7 @@ wal_writer_start(struct recovery_state *state) return 0; } +/** Stop and destroy the writer thread (at shutdown). */ static int wal_writer_stop(struct recovery_state *state) { @@ -1340,6 +1373,11 @@ error: return -1; } +/** + * Pop a bulk of requests to write to disk to process. + * Block on the condition only if we have no other work to + * do. Loop in case of a spurious wakeup. + */ struct wal_fifo wal_writer_pop(struct wal_writer *writer, bool input_was_empty) { @@ -1354,6 +1392,9 @@ wal_writer_pop(struct wal_writer *writer, bool input_was_empty) return input; } +/** + * Write a single request to disk. + */ static int write_to_disk(struct recovery_state *r, struct wal_write_request *req) { @@ -1446,6 +1487,7 @@ fail: return -1; } +/** WAL writer thread main loop. */ static void * wal_writer_thread(void *worker_args) { @@ -1474,13 +1516,21 @@ wal_writer_thread(void *worker_args) STAILQ_CONCAT(&writer->output, &input); } tt_pthread_mutex_unlock(&writer->mutex); - + /* + * Handle the case when a shutdown request came before + * we were able to awake all fibers waiting on the + * previous pack. + */ if (input_was_empty == false) ev_async_send(&writer->async); write_to_disk(r, NULL); return NULL; } +/** + * WAL writer main entry point: queue a single request + * to be written to disk and wait until this task is completed. + */ int wal_write(struct recovery_state *r, u16 tag, u16 op, u64 cookie, i64 lsn, struct tbuf *row) @@ -1554,6 +1604,12 @@ recovery_update_mode(const char *mode, double fsync_delay) { struct recovery_state *r = recovery_state; (void) mode; + /* No mutex lock: let's not bother with whether + * or not a WAL writer thread is present, and + * if it's present, the delay will be propagated + * to it whenever there is a next lock/unlock of + * wal_writer->mutex. + */ r->wal_class->fsync_delay = fsync_delay; } -- GitLab