> On Jul 7, 2016, at 11:03 AM, Pierre Habouzit <pie...@habouzit.net> wrote: > >> On Jul 7, 2016, at 10:01 AM, Karl via swift-corelibs-dev >> <swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>> wrote: >> >> Hi, >> >> I’d like to propose a change to the new GCD API; that DispatchWorkItems be >> retained by their groups (and in turn, for them to be retained by their >> queues). This allows for whoever created the work item to create a weak >> reference to it, as an indicator for whether or not it has finished >> executing.
Oh also, and that is a common misconception, groups have absolutely no ownership information so this “(… to be retained by their queues)” is not something that exists or is a thing. What does exist is that a group is never destroyed while it has unbalanced enter/leaves, and the DispatchWorkItem is definitely retained by any queue it has been async()ed to (you can async a single WorkItem to several places, however that precludes you from using .notify() or .wait()). >> For example, let’s say I have some kind of class which manages a library of >> files. I want to have a refresh operation which runs on a background queue, >> enumerating the documents and perhaps even opening them and extracting some >> metadata: >> >> class DocumentLibrary { >> >> weak var refreshOperation : DispatchWorkItem? >> >> func refresh(force:Bool = false) { >> >> If let ongoingOperation = refreshOperation { >> if force == true { >> ongoingOperation.cancel() // force an update >> } >> else { >> return // already refreshing >> } >> } >> >> refreshOperation = DispatchWorkItem(….) // processes the files, >> returns the results on the main queue >> DispatchQueue.global().async(refreshOperation) >> } >> } >> >> This relies on the fact that weak references are thread-safe, and avoids the >> need for an explicit completion handler which nils the variable. >> >> Thoughts? > > DispatchWorkItem.init() taking a group was a mistake and we are preparing an > updated proposal to remove this and instead have a queue.async() overload > that can take both a WorkItem and a group. The reason why is that the > semantics of having a group attached to a DispatchWorkItem() is not useful, > you most of the time want to enter() the group when the WorkItem is created, > and have it consumed when it has run, but that not what the implementation > does, it instead will enter the group at async() time. > > However, if we changed the semantics to enter() at creation time, it would > mean that the WorkItem could be asynced only once, which is a huge pitfall > and design issue too. > > > As far as your proposal goes: > - dispatch groups are a single atomic counter and have no storage to own a > reference on the WorkItem, changing this would dramatically change the > performance profile of that existing API which is a non starter > - anything could still have references on the DispatchWorkItem and using weak > references to poll for completion is both a bad design (IMO) and fraught with > peril > > DispatchWorkItem come with .notify() and .wait() which are the things you > should use for this. You should have a .notify() block that sets a boolean, > on your class to track this. > > Also using the global() queues is also fraught with another peril: thread > explosion, but that’s probably outside of the scope of your feature request. -Pierre
_______________________________________________ swift-corelibs-dev mailing list swift-corelibs-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-corelibs-dev