public static SafeXmlReaderWriter Get(IScopeProvider scopeProvider, SystemLock xmlLock, XmlDocument xml, Action <XmlDocument> refresh, Action <XmlDocument, bool> apply, bool writer) { var scopeContext = scopeProvider.Context; // no real scope = just create a reader/writer instance if (scopeContext == null) { // obtain exclusive access to xml and create reader/writer var releaser = xmlLock.Lock(); return(new SafeXmlReaderWriter(releaser, xml, refresh, apply, writer, false)); } // get or create an enlisted reader/writer var rw = scopeContext.Enlist(EnlistKey, () => // creator { // obtain exclusive access to xml and create reader/writer var releaser = xmlLock.Lock(); return(new SafeXmlReaderWriter(releaser, xml, refresh, apply, writer, true)); }, (completed, item) => // action { item.DisposeForReal(completed); }, EnlistPriority); // ensure it's not already in-use - should never happen, just being super safe if (rw._using) { throw new InvalidOperationException("panic: used."); } rw._using = true; return(rw); }
public Task <bool> AcquireLockAsync(int millisecondsTimeout) { // signal other instances that we want the lock, then wait on the lock, // which may timeout, and this is accepted - see comments below // signal, then wait for the lock, then make sure the event is // reset (maybe there was noone listening..) _signal.Set(); // if more than 1 instance reach that point, one will get the lock // and the other one will timeout, which is accepted //This can throw a TimeoutException - in which case should this be in a try/finally to ensure the signal is always reset. try { _lockRelease = _systemLock.Lock(millisecondsTimeout); return(Task.FromResult(true)); } catch (TimeoutException ex) { _logger.Error <MainDomSemaphoreLock>(ex); return(Task.FromResult(false)); } finally { // we need to reset the event, because otherwise we would end up // signaling ourselves and committing suicide immediately. // only 1 instance can reach that point, but other instances may // have started and be trying to get the lock - they will timeout, // which is accepted _signal.Reset(); } }
public override void Run() { lock (_locko) { _logger.Debug <XmlStoreFilePersister>("Run now (sync)."); // not really needed but safer (it's only us invoking Run, but the method is public...) _released = true; } using (_runLock.Lock()) { _store.SaveXmlToFile(); } }