/// <summary> /// 增加 checkpoint 完成一次以后执行的动作,每次 FlushReadWriteLock.EnterWriteLock() /// 之前的动作在本次checkpoint完成时执行,之后的动作在下一次DoCheckpoint后执行。 /// </summary> /// <param name="act"></param> internal void AddActionAndPulse(Action act) { FlushReadWriteLock.EnterReadLock(); try { lock (this) { actionPending.Add(act); Monitor.Pulse(this); } } finally { FlushReadWriteLock.ExitReadLock(); } }
private void DoCheckpoint() { // encodeN foreach (var db in databases) { db.EncodeN(); } // snapshot { FlushReadWriteLock.EnterWriteLock(); try { actionCurrent = actionPending; actionPending = new List <Action>(); foreach (var db in databases) { db.Snapshot(); } } finally { FlushReadWriteLock.ExitWriteLock(); } } // flush { readys = new ManualResetEvent[databases.Count]; int i = 0; foreach (var v in databases) { v.CommitReady.Reset(); readys[i++] = v.CommitReady; } if (databases.Count > 1) { i = 0; Task[] flushTasks = new Task[databases.Count]; // 多数据库时,必须把flush放在线程中执行,db.Flush内部需要回调this.WaitAll。 // flush 必须都能得到执行,flushThreads的数量必须足够。 foreach (var db in databases) { TaskCompletionSource <bool> future = new TaskCompletionSource <bool>(); flushThreads.QueueUserWorkItem( () => Util.Task.Call(() => { db.Flush(this); future.SetResult(true); }, "Zeze.Checkpoint.Flush" )); flushTasks[i++] = future.Task; } Task.WaitAll(flushTasks); } else { // 只有一个Database。同步执行。 foreach (var db in databases) { db.Flush(this); } } readys = null; } // cleanup foreach (var db in databases) { db.Cleanup(); } }