public void TestLayerLocking()
        {
            try
            {
                const string TEST_SCENENAME  = "TestSceneLocking";
                const string TEST_SCENENAME2 = "TestSceneLocking_SaveAsTest";

                // Create a new project and scene
                TestManager.Helpers.CreateTestScene(TEST_SCENENAME);
                EditorProject project    = EditorApp.Project;
                IScene        scene      = project.Scene;
                Layer         firstLayer = scene.Layers[0];

                // First layer must be writeable
                Assert.IsTrue(firstLayer.OwnsLock);
                Assert.IsTrue(firstLayer.SaveToFile());

                // close scene
                string layerFilePath = firstLayer.AbsoluteLayerFilename;
                firstLayer = null;
                scene.Close();
                Assert.IsNull(project.Scene);

                // Get external lock on layer file
                IFileLock extFileLock = EditorManager.FileLockFactory.GetFileLock(layerFilePath);
                Assert.IsTrue(extFileLock.TryLock());

                // Reopen scene: must fail on saving layer (locked externally)
                Assert.IsTrue(project.OpenScene(TEST_SCENENAME));
                scene      = project.Scene;
                firstLayer = scene.Layers[0];
                Assert.IsFalse(firstLayer.OwnsLock);

                // Release lock: OwnsWriteLock state must get updated
                extFileLock.Unlock();
                // Give windows time to inform the file watcher
                System.Threading.Thread.Sleep(1000); TestManager.Helpers.ProcessEvents();
                // And then give the file watcher time to send his queued/delayed notification
                System.Threading.Thread.Sleep(1000); TestManager.Helpers.ProcessEvents();
                Assert.IsTrue(firstLayer.LockStatus == Layer.LayerLockStatus_e.NotLocked);

                // Let the scene lock the layer again: saving file must be successful
                firstLayer.TryLock(null, false);
                Assert.IsTrue(firstLayer.OwnsLock);
                Assert.IsTrue(firstLayer.SaveToFile());

                // Getting external lock must fail (since file is locked by scene)
                Assert.IsFalse(extFileLock.TryLock());

                // Rename the scene file
                Assert.IsTrue(scene.SaveAs(TEST_SCENENAME2));
                string renamedLayerFilePath = firstLayer.AbsoluteLayerFilename;
                Assert.IsTrue(renamedLayerFilePath != layerFilePath);

                // Getting external lock must work after scene-save-as
                Assert.IsTrue(firstLayer.OwnsLock);
                Assert.IsTrue(extFileLock.TryLock());
                extFileLock.Unlock();

                // Getting external lock on renamed file must fail
                IFileLock extFileLockRenamed = EditorManager.FileLockFactory.GetFileLock(renamedLayerFilePath);
                Assert.IsFalse(extFileLockRenamed.TryLock());

                // Verify that a scene can't be opened without closing it at first
                // (important, since we otherwise still have the lock on the old scene)
                Assert.IsFalse(project.OpenScene(TEST_SCENENAME));

                // Close scene
                scene.Close();
                Assert.IsNull(project.Scene);

                // Test correct behaviour for readonly layer files
                {
                    // Set the layer as readonly (as done by some version control systems
                    // when using exclusive locking)
                    File.SetAttributes(layerFilePath, File.GetAttributes(layerFilePath) | FileAttributes.ReadOnly);

                    // Reopen scene
                    Assert.IsTrue(project.OpenScene(TEST_SCENENAME));
                    scene      = project.Scene;
                    firstLayer = scene.Layers[0];

                    // Layer must not be locked due to being readonly.
                    Assert.IsFalse(firstLayer.OwnsLock);
                    Assert.AreEqual(Layer.LayerLockStatus_e.ReadOnly, firstLayer.LockStatus);

                    // Close scene
                    scene.Close();
                    Assert.IsNull(project.Scene);

                    // Set the layer as readonly (as done by some version control systems
                    // when using exclusive locking)
                    File.SetAttributes(layerFilePath, File.GetAttributes(layerFilePath) & (~FileAttributes.ReadOnly));
                }

                TestManager.Helpers.CloseTestProject();
            }
            catch (Exception ex)
            {
                EditorManager.DumpException(ex);
                throw ex;
            }
        }
Exemplo n.º 2
0
		internal virtual void UnlockProject()
		{
			if (m_fileLock != null)
			{
				m_fileLock.ReleaseLock();
				m_fileLock = null;
			}
		}
Exemplo n.º 3
0
        public AcquireLockAction ShouldAcquireLock(IFileLock fileLock)
        {
            if (lockIo.LockExists(LockFilePath))
            {
                //Someone else owns the lock
                if (fileLock is OtherProcessHasExclusiveLockOnFileLock)
                {
                    //we couldn't read the file as some other process has it open exlusively
                    return(AcquireLockAction.DontAcquireLock);
                }

                if (fileLock is UnableToDeserialiseLockFile nonDeserialisedLockFile)
                {
                    if ((DateTime.Now - nonDeserialisedLockFile.CreationTime).TotalSeconds > LockTimeout.TotalSeconds)
                    {
                        log.Warn("Lock file existed but was not readable, and has existed for longer than lock timeout. Taking lock.");
                        return(AcquireLockAction.AcquireLock);
                    }

                    return(AcquireLockAction.DontAcquireLock);
                }

                //the file no longer exists
                if (fileLock is MissingFileLock)
                {
                    return(AcquireLockAction.AcquireLock);
                }

                var concreteFileLock = fileLock as FileLock;
                if (concreteFileLock == null)
                {
                    return(AcquireLockAction.AcquireLock);
                }

                //This lock belongs to this process - we can reacquire the lock
                if (concreteFileLock.BelongsToCurrentProcessAndThread())
                {
                    return(AcquireLockAction.AcquireLock);
                }

                if (!processFinder.ProcessIsRunning((int)concreteFileLock.ProcessId, concreteFileLock.ProcessName ?? ""))
                {
                    log.Warn($"Process {concreteFileLock.ProcessId}, thread {concreteFileLock.ThreadId} had lock, but appears to have crashed. Taking lock.");

                    return(AcquireLockAction.AcquireLock);
                }

                var lockWriteTime = new DateTime(concreteFileLock.Timestamp);
                //The lock has not timed out - we can't acquire it
                if (!(Math.Abs((DateTime.Now - lockWriteTime).TotalSeconds) > LockTimeout.TotalSeconds))
                {
                    return(AcquireLockAction.DontAcquireLock);
                }

                log.Warn($"Forcibly taking lock from process {concreteFileLock.ProcessId}, thread {concreteFileLock.ThreadId} as lock has timed out. If this happens regularly, please contact Octopus Support.");

                return(AcquireLockAction.ForciblyAcquireLock);
            }

            return(AcquireLockAction.AcquireLock);
        }
Exemplo n.º 4
0
		internal virtual void LockProject()
		{
			m_fileLock = SimpleFileLock.CreateFromFilePath(ProjectId.Path + ".lock");
			if (!m_fileLock.TryAcquireLock())
				throw new FdoFileLockedException(String.Format(Properties.Resources.kstidLockFileLocked, ProjectId.Name), true);
			m_lastWriteTime = File.GetLastWriteTimeUtc(ProjectId.Path);
		}