/// <summary> /// Updates this audio component. Always runs on the audio thread. /// </summary> public void Update() { ThreadSafety.EnsureNotUpdateThread(); if (IsDisposed) { throw new ObjectDisposedException(ToString(), "Can not update disposed audio components."); } FrameStatistics.Add(StatisticsCounterType.TasksRun, PendingActions.Count); FrameStatistics.Increment(StatisticsCounterType.Components); while (!IsDisposed && PendingActions.TryDequeue(out Task task)) { task.RunSynchronously(); } if (!IsDisposed) { UpdateState(); } UpdateChildren(); }
public void CreateIndex(string name, IIndex index) { CBDebug.MustNotBeNull(Log.To.Database, Tag, nameof(name), name); CBDebug.MustNotBeNull(Log.To.Database, Tag, nameof(index), index); ThreadSafety.DoLocked(() => { CheckOpen(); var concreteIndex = Misc.TryCast <IIndex, QueryIndex>(index); var jsonObj = concreteIndex.ToJSON(); var json = JsonConvert.SerializeObject(jsonObj); LiteCoreBridge.Check(err => { var internalOpts = concreteIndex.Options; // For some reason a "using" statement here causes a compiler error try { return(Native.c4db_createIndex(c4db, name, json, concreteIndex.IndexType, &internalOpts, err)); } finally { internalOpts.Dispose(); } }); }); }
internal DictionaryObject(MDict dict, bool isMutable) { _dict.InitAsCopyOf(dict, isMutable); _threadSafety = SetupThreadSafety(); }
internal DictionaryObject(MValue mv, MCollection parent) { _dict.InitInSlot(mv, parent); _threadSafety = SetupThreadSafety(); }
internal DictionaryObject() { _threadSafety = SetupThreadSafety(); }
/// <summary> /// Constructs a replicator based on the given <see cref="ReplicatorConfiguration"/> /// </summary> /// <param name="config">The configuration to use to create the replicator</param> public Replicator([NotNull] ReplicatorConfiguration config) { Config = CBDebug.MustNotBeNull(Log.To.Sync, Tag, nameof(config), config).Freeze(); _databaseThreadSafety = Config.Database.ThreadSafety; }
/// <summary> /// Invalidates draw matrix and autosize caches. /// </summary> /// <returns>If the invalidate was actually necessary.</returns> public virtual bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { if (invalidation == Invalidation.None) { return(false); } ThreadSafety.EnsureUpdateThread(); OnInvalidate?.Invoke(); if (shallPropagate && Parent != null && source != Parent) { Parent.Invalidate(Parent.InvalidationEffectByChildren(invalidation), this, false); } bool alreadyInvalidated = true; if ((invalidation & Invalidation.SizeInParentSpace) > 0) { alreadyInvalidated &= !boundingSizeBacking.Invalidate(); } // Either ScreenSize OR ScreenPosition if ((invalidation & Invalidation.ScreenSpaceQuad) > 0) { alreadyInvalidated &= !screenSpaceDrawQuadBacking.Invalidate(); } // Either ScreenSize OR ScreenPosition OR Colour if ((invalidation & Invalidation.DrawInfo) > 0) { alreadyInvalidated &= !drawInfoBacking.Invalidate(); } if ((invalidation & Invalidation.Visibility) > 0) { alreadyInvalidated &= !isVisibleBacking.Invalidate(); } if (alreadyInvalidated || !shallPropagate) { return(!alreadyInvalidated); } if (children != null) { foreach (var c in children) { Debug.Assert(c != source); Invalidation childInvalidation = invalidation; //if (c.SizeMode == InheritMode.None) childInvalidation = childInvalidation & ~Invalidation.SizeInParentSpace; c.Invalidate(childInvalidation, this); } } return(!alreadyInvalidated); }
public Docs LoadDocs(XElement dElement, string filePath) { dElement = TransformDocs(dElement); if (dElement == null) { return(null); } var remarks = dElement.Element("remarks"); string remarksText = NormalizeDocsElement(remarks, true); string examplesText = null; if (remarksText != null) { if (remarksText.Contains("</format>")) { Console.WriteLine(filePath); Console.WriteLine(remarksText); } remarksText = remarksText.Replace("## Remarks", "").Trim(); if (remarksText.Contains("## Examples")) { var pos = remarksText.IndexOf("## Examples"); examplesText = remarksText.Substring(pos).Replace("## Examples", "").Trim(); remarksText = remarksText.Substring(0, pos).Trim(); } } remarksText = DowngradeMarkdownHeaders(remarksText); var examples = dElement.Elements("example"); if (examples != null && examples.Count() > 0) { examplesText = string.IsNullOrEmpty(examplesText) ? "" : examplesText + "\n\n"; examplesText += string.Join("\n\n", examples.Select(example => NormalizeDocsElement(example))); } List <RelatedTag> related = null; var relatedElements = dElement.Elements("related")?.ToList(); if (relatedElements?.Count > 0) { related = LoadRelated(relatedElements); } Dictionary <string, string> additionalNotes = null; var blocks = dElement.Elements("block")?.Where(p => !string.IsNullOrEmpty(p.Attribute("type")?.Value)).ToList(); if (blocks != null && blocks.Count > 0) { additionalNotes = new Dictionary <string, string>(); foreach (var block in blocks) { var valElement = block; var elements = block.Elements().ToArray(); if (elements?.Length == 1 && elements[0].Name.LocalName == "p") { valElement = elements[0]; } additionalNotes[block.Attribute("type").Value] = NormalizeDocsElement(GetInnerXml(valElement)); } } string threadSafetyContent = null; ThreadSafety threadSafety = null; var threadSafeEle = dElement.Element("threadsafe"); if (threadSafeEle != null) { threadSafetyContent = NormalizeDocsElement(GetInnerXml(threadSafeEle)); var supportedAttr = threadSafeEle.Attribute("supported"); threadSafety = new ThreadSafety() { CustomContent = threadSafetyContent, Supported = supportedAttr?.Value?.Equals("true", StringComparison.OrdinalIgnoreCase), MemberScope = threadSafeEle.Attribute("memberScope")?.Value }; } var inheritdocEle = dElement.Element("inheritdoc"); InheritDoc inheritDoc = null; if (inheritdocEle != null) { inheritDoc = new InheritDoc(); // TODO: other attributes parse } return(new Docs() { Summary = NormalizeDocsElement(dElement.Element("summary")), Remarks = remarksText, Examples = examplesText, AltMemberCommentIds = MergeAltmemberAndSeealsoToAltMemberCommentsIds(dElement),//dElement.Elements("altmember")?.Select(alt => alt.Attribute("cref").Value).ToList(), Related = related, Exceptions = dElement.Elements("exception")?.Select(el => GetTypedContent(el, filePath)).ToList(), Permissions = dElement.Elements("permission")?.Select(el => GetTypedContent(el, filePath)).ToList(), Parameters = dElement.Elements("param")?.Where(p => !string.IsNullOrEmpty(p.Attribute("name").Value)).ToDictionary(p => p.Attribute("name").Value, p => NormalizeDocsElement(p)), TypeParameters = dElement.Elements("typeparam")?.Where(p => !string.IsNullOrEmpty(p.Attribute("name").Value)).ToDictionary(p => p.Attribute("name").Value, p => NormalizeDocsElement(GetInnerXml(p))), AdditionalNotes = additionalNotes, Returns = NormalizeDocsElement(dElement.Element("returns")), //<value> will be transformed to <returns> by xslt in advance ThreadSafety = threadSafetyContent, ThreadSafetyInfo = threadSafety, Since = NormalizeDocsElement(dElement.Element("since")?.Value), AltCompliant = dElement.Element("altCompliant")?.Attribute("cref")?.Value, InternalOnly = dElement.Element("forInternalUseOnly") != null, Inheritdoc = inheritDoc }); }
internal ArrayObject([NotNull] ArrayObject original, bool mutable) : this(original._array, mutable) { _threadSafety = SetupThreadSafety(); }
internal void ResolveConflict([NotNull] string docID, [NotNull] IConflictResolver resolver) { Debug.Assert(docID != null); Document doc = null, otherDoc = null, baseDoc = null; var inConflict = true; while (inConflict) { ThreadSafety.DoLocked(() => { LiteCoreBridge.Check(err => Native.c4db_beginTransaction(_c4db, err)); try { doc = new Document(this, docID); if (!doc.Exists) { doc.Dispose(); return; } otherDoc = new Document(this, docID); if (!otherDoc.Exists) { doc.Dispose(); otherDoc.Dispose(); return; } otherDoc.SelectConflictingRevision(); baseDoc = new Document(this, docID); if (!baseDoc.SelectCommonAncestor(doc, otherDoc) || baseDoc.ToDictionary() == null) { baseDoc.Dispose(); baseDoc = null; } LiteCoreBridge.Check(err => Native.c4db_endTransaction(_c4db, true, err)); } catch (Exception) { doc?.Dispose(); otherDoc?.Dispose(); baseDoc?.Dispose(); LiteCoreBridge.Check(err => Native.c4db_endTransaction(_c4db, false, err)); } }); var conflict = new Conflict(doc, otherDoc, baseDoc); var logID = new SecureLogString(doc.Id, LogMessageSensitivity.PotentiallyInsecure); Log.To.Database.I(Tag, $"Resolving doc '{logID}' with {resolver.GetType().Name} (mine={doc.RevID}, theirs={otherDoc.RevID}, base={baseDoc?.RevID})"); Document resolved = null; try { resolved = resolver.Resolve(conflict); if (resolved == null) { throw new LiteCoreException(new C4Error(C4ErrorCode.Conflict)); } SaveResolvedDocument(resolved, conflict); inConflict = false; } catch (LiteCoreException e) { if (e.Error.domain == C4ErrorDomain.LiteCoreDomain && e.Error.code == (int)C4ErrorCode.Conflict) { continue; } throw; } finally { resolved?.Dispose(); if (resolved != doc) { doc?.Dispose(); } if (resolved != otherDoc) { otherDoc?.Dispose(); } if (resolved != baseDoc) { baseDoc?.Dispose(); } } } }
public Document GetDocument(string id) { CBDebug.MustNotBeNull(Log.To.Database, Tag, nameof(id), id); return(ThreadSafety.DoLocked(() => GetDocumentInternal(id))); }
private void Save([NotNull] Document doc, C4Document **outDoc, C4Document *baseDoc, bool deletion) { var revFlags = (C4RevisionFlags)0; if (deletion) { revFlags = C4RevisionFlags.Deleted; } byte[] body = null; if (!deletion && !doc.IsEmpty) { body = doc.Encode(); var root = Native.FLValue_FromTrustedData(body); if (root == null) { Log.To.Database.E(Tag, "Failed to encode document body properly. Aborting save of document!"); return; } var rootDict = Native.FLValue_AsDict(root); if (rootDict == null) { Log.To.Database.E(Tag, "Failed to encode document body properly. Aborting save of document!"); return; } ThreadSafety.DoLocked(() => { if (Native.c4doc_dictContainsBlobs(rootDict, SharedStrings.SharedKeys)) { revFlags |= C4RevisionFlags.HasAttachments; } }); } else if (doc.IsEmpty) { FLEncoder *encoder = SharedEncoder; Native.FLEncoder_BeginDict(encoder, 0); Native.FLEncoder_EndDict(encoder); body = Native.FLEncoder_Finish(encoder, null); Native.FLEncoder_Reset(encoder); } var rawDoc = baseDoc != null ? baseDoc : doc.c4Doc?.HasValue == true ? doc.c4Doc.RawDoc : null; if (rawDoc != null) { doc.ThreadSafety.DoLocked(() => { ThreadSafety.DoLocked(() => { *outDoc = (C4Document *)NativeHandler.Create() .AllowError((int)C4ErrorCode.Conflict, C4ErrorDomain.LiteCoreDomain).Execute( err => Native.c4doc_update(rawDoc, body, revFlags, err)); }); }); } else { ThreadSafety.DoLocked(() => { *outDoc = (C4Document *)NativeHandler.Create() .AllowError((int)C4ErrorCode.Conflict, C4ErrorDomain.LiteCoreDomain).Execute( err => Native.c4doc_create(_c4db, doc.Id, body, revFlags, err)); }); } }
private Document Save([NotNull] Document document, bool deletion) { if (document.IsInvalidated) { throw new CouchbaseLiteException(StatusCode.NotAllowed, "Cannot save or delete a MutableDocument that has already been used to save or delete"); } if (deletion && document.RevID == null) { throw new CouchbaseLiteException(StatusCode.NotAllowed, "Cannot delete a document that has not yet been saved"); } var docID = document.Id; var doc = document; Document baseDoc = null, otherDoc = null; C4Document *newDoc = null; Document retVal = null; while (true) { var resolve = false; retVal = ThreadSafety.DoLocked(() => { VerifyDB(doc); LiteCoreBridge.Check(err => Native.c4db_beginTransaction(_c4db, err)); try { if (deletion) { // Check for no-op case if the document does not exist var curDoc = (C4Document *)NativeHandler.Create().AllowError(new C4Error(C4ErrorCode.NotFound)) .Execute(err => Native.c4doc_get(_c4db, docID, true, err)); if (curDoc == null) { (document as MutableDocument)?.MarkAsInvalidated(); return(null); } Native.c4doc_free(curDoc); } var newDocOther = newDoc; Save(doc, &newDocOther, baseDoc?.c4Doc?.HasValue == true ? baseDoc.c4Doc.RawDoc : null, deletion); if (newDocOther != null) { // Save succeeded, so commit newDoc = newDocOther; LiteCoreBridge.Check(err => { var success = Native.c4db_endTransaction(_c4db, true, err); if (!success) { Native.c4doc_free(newDoc); } return(success); }); (document as MutableDocument)?.MarkAsInvalidated(); baseDoc?.Dispose(); return(new Document(this, docID, new C4DocumentWrapper(newDoc))); } // There was a conflict if (deletion && !doc.IsDeleted) { var deletedDoc = doc.ToMutable(); deletedDoc.MarkAsDeleted(); doc = deletedDoc; } if (doc.c4Doc != null) { baseDoc = new Document(this, docID, doc.c4Doc.Retain <C4DocumentWrapper>()); } otherDoc = new Document(this, docID); if (!otherDoc.Exists) { LiteCoreBridge.Check(err => Native.c4db_endTransaction(_c4db, false, err)); return(null); } } catch (Exception) { baseDoc?.Dispose(); otherDoc?.Dispose(); LiteCoreBridge.Check(err => Native.c4db_endTransaction(_c4db, false, err)); throw; } resolve = true; LiteCoreBridge.Check(err => Native.c4db_endTransaction(_c4db, false, err)); return(null); }); if (!resolve) { return(retVal); } // Resolve Conflict Document resolved = null; try { var resolver = Config.ConflictResolver; var conflict = new Conflict(doc, otherDoc, baseDoc); resolved = resolver.Resolve(conflict); if (resolved == null) { throw new LiteCoreException(new C4Error(C4ErrorCode.Conflict)); } } finally { baseDoc?.Dispose(); if (!ReferenceEquals(resolved, otherDoc)) { otherDoc?.Dispose(); } } retVal = ThreadSafety.DoLocked(() => { var current = new Document(this, docID); if (resolved.RevID == current.RevID) { (document as MutableDocument)?.MarkAsInvalidated(); current.Dispose(); return(resolved); // Same as current } // For saving doc = resolved; baseDoc = current; deletion = resolved.IsDeleted; return(null); }); if (retVal != null) { return(retVal); } } }
internal DatabaseSource([NotNull] Database database, [NotNull] ThreadSafety threadSafety) : base(database, threadSafety) { Debug.Assert(database != null); }
public DatabaseSource(Database database, [NotNull] ThreadSafety threadSafety) : base(database, threadSafety) { }
internal ArrayObject() { _threadSafety = SetupThreadSafety(); }
internal ArrayObject([NotNull] FleeceMutableArray array, bool isMutable) { _array.InitAsCopyOf(array, isMutable); _threadSafety = SetupThreadSafety(); }
internal override bool Upload() { // We should never run raw OGL calls on another thread than the main thread due to race conditions. ThreadSafety.EnsureDrawThread(); if (isDisposed) { return(false); } IntPtr dataPointer; GCHandle? h0; TextureUpload upload; bool didUpload = false; while (uploadQueue.TryDequeue(out upload)) { if (upload.Data.Length == 0) { h0 = null; dataPointer = IntPtr.Zero; } else { h0 = GCHandle.Alloc(upload.Data, GCHandleType.Pinned); dataPointer = h0.Value.AddrOfPinnedObject(); didUpload = true; } try { // Do we need to generate a new texture? if (textureId <= 0 || internalWidth < width || internalHeight < height) { internalWidth = width; internalHeight = height; // We only need to generate a new texture if we don't have one already. Otherwise just re-use the current one. if (textureId <= 0) { int[] textures = new int[1]; GL.GenTextures(1, textures); textureId = textures[0]; GLWrapper.BindTexture(textureId); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); updateWrapMode(); } else { GLWrapper.BindTexture(textureId); } if (width == upload.Bounds.Width && height == upload.Bounds.Height || dataPointer == IntPtr.Zero) { GL.TexImage2D(TextureTarget2d.Texture2D, upload.Level, TextureComponentCount.Rgba, width, height, 0, upload.Format, PixelType.UnsignedByte, dataPointer); } else { initializeLevel(upload.Level, width, height); GL.TexSubImage2D(TextureTarget2d.Texture2D, upload.Level, upload.Bounds.X, upload.Bounds.Y, upload.Bounds.Width, upload.Bounds.Height, upload.Format, PixelType.UnsignedByte, dataPointer); } } // Just update content of the current texture else if (dataPointer != IntPtr.Zero) { GLWrapper.BindTexture(textureId); if (!manualMipmaps && upload.Level > 0) { //allocate mipmap levels int level = 1; int d = 2; while (width / d > 0) { initializeLevel(level, width / d, height / d); level++; d *= 2; } manualMipmaps = true; } int div = (int)Math.Pow(2, upload.Level); GL.TexSubImage2D(TextureTarget2d.Texture2D, upload.Level, upload.Bounds.X / div, upload.Bounds.Y / div, upload.Bounds.Width / div, upload.Bounds.Height / div, upload.Format, PixelType.UnsignedByte, dataPointer); } } finally { h0?.Free(); upload?.Dispose(); } } if (didUpload && !manualMipmaps) { GL.Hint(HintTarget.GenerateMipmapHint, HintMode.Nicest); GL.GenerateMipmap(TextureTarget.Texture2D); } return(didUpload); }
internal ArrayObject(MValue mv, MCollection parent) { _array.InitInSlot(mv, parent); _threadSafety = SetupThreadSafety(); }
// Does the command mutate global state? internal static bool CommandDefined(TpmCc command) { return(ThreadSafety.ContainsKey(command)); }
internal override bool Upload() { // We should never run raw OGL calls on another thread than the main thread due to race conditions. ThreadSafety.EnsureDrawThread(); if (IsDisposed) { throw new ObjectDisposedException(ToString(), "Can not upload data to a disposed texture."); } bool didUpload = false; while (uploadQueue.TryDequeue(out TextureUpload upload)) { IntPtr dataPointer; GCHandle?h0; if (upload.Data.Length == 0) { h0 = null; dataPointer = IntPtr.Zero; } else { h0 = GCHandle.Alloc(upload.Data, GCHandleType.Pinned); dataPointer = h0.Value.AddrOfPinnedObject(); didUpload = true; } try { // Do we need to generate a new texture? if (textureId <= 0 || internalWidth != width || internalHeight != height) { internalWidth = width; internalHeight = height; // We only need to generate a new texture if we don't have one already. Otherwise just re-use the current one. if (textureId <= 0) { int[] textures = new int[1]; GL.GenTextures(1, textures); textureId = textures[0]; GLWrapper.BindTexture(this); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)(manualMipmaps ? filteringMode : (filteringMode == All.Linear ? All.LinearMipmapLinear : All.Nearest))); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)filteringMode); // 33085 is GL_TEXTURE_MAX_LEVEL, which is not available within TextureParameterName. // It controls the amount of mipmap levels generated by GL.GenerateMipmap later on. GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)33085, MAX_MIPMAP_LEVELS); updateWrapMode(); } else { GLWrapper.BindTexture(this); } if (width == upload.Bounds.Width && height == upload.Bounds.Height || dataPointer == IntPtr.Zero) { GL.TexImage2D(TextureTarget2d.Texture2D, upload.Level, TextureComponentCount.Srgb8Alpha8, width, height, 0, upload.Format, PixelType.UnsignedByte, dataPointer); } else { initializeLevel(upload.Level, width, height); GL.TexSubImage2D(TextureTarget2d.Texture2D, upload.Level, upload.Bounds.X, upload.Bounds.Y, upload.Bounds.Width, upload.Bounds.Height, upload.Format, PixelType.UnsignedByte, dataPointer); } } // Just update content of the current texture else if (dataPointer != IntPtr.Zero) { GLWrapper.BindTexture(this); if (!manualMipmaps && upload.Level > 0) { //allocate mipmap levels int level = 1; int d = 2; while (width / d > 0) { initializeLevel(level, width / d, height / d); level++; d *= 2; } manualMipmaps = true; } int div = (int)Math.Pow(2, upload.Level); GL.TexSubImage2D(TextureTarget2d.Texture2D, upload.Level, upload.Bounds.X / div, upload.Bounds.Y / div, upload.Bounds.Width / div, upload.Bounds.Height / div, upload.Format, PixelType.UnsignedByte, dataPointer); } } finally { h0?.Free(); upload.Dispose(); } } if (didUpload && !manualMipmaps) { GL.Hint(HintTarget.GenerateMipmapHint, HintMode.Nicest); GL.GenerateMipmap(TextureTarget.Texture2D); } return(didUpload); }
public ILearner GetLearner(int result) { ILearner learner = null; switch (result) { case 1: learner = new ThreadSafety(); break; case 2: learner = new ThreadAffinityApp(); break; case 3: learner = new SignalAutoEvent(); break; case 4: learner = new TwoWaySignal(); break; case 5: learner = new SignalManualReset(); break; case 6: learner = new CountDown(); break; case 7: learner = new TPLIntro(); break; case 8: learner = new ParallelVsNormal(); break; case 9: learner = new Cancellation(); break; case 10: learner = new ContinuationWithState(); break; case 11: learner = new TaskCompletionSource(); break; case 12: learner = new PLINQIntro(); break; case 13: learner = new PLINQDegreeParallelism(); break; case 14: learner = new PLINQForAll(); break; case 15: learner = new PLINQMergeOptions(); break; case 16: learner = new TAPIntro(); break; default: learner = new ThreadSafety(); break; } return(learner); }