Swift: Recursive graphs of globals deadlock at runtime
| Originator: | rix.rob | ||
| Number: | rdar://18340291 | Date Originated: | 15-Sep-2014 03:22 PM |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode-Beta (6A1027) |
| Classification: | Serious Bug | Reproducible: | Always |
Summary:
When declaring a recursive graph of globals, you get a deadlock at runtime because it’s attempting to call dispatch_once reentrantly.
Steps to Reproduce:
1. Write a recursive graph of globals, for example a recursive graph of functions.
2. Use it.
See notes for details why, but you basically need to use two files, one which has something like this:
func c(string: String) -> String -> (String, String)? { return { input in nil } }
func | <T>(lhs: String -> (T, String)?, rhs: String -> (T, String)?) -> String -> (T, String)? { return { input in nil } }
// Note that these are mutually recursive.
let x: String -> (String, String)? = c("0") | y
let y = c("1") | x
and the other :
// Since globals are initialized lazily, we need to actually call one of the functions.
x("")
// It never gets this far; it has deadlocked.
println("done")
Expected Results:
I expected it to produce the recursive graph of globals at runtime and run them as specified.
Actual Results:
When you attempt to use the recursive graph, it deadlocks within swift_once/dispatch_once, because it’s calling that reentrantly.
Regression:
N/A
Notes:
I can’t figure out how to do this with a #! script, so you’ll need to use a couple of files in a command-line tool project. Sample project will be attached shortly.
There are a couple of plausible resolutions I see:
- disallow recursively-defined globals like this, requiring the developer to resolve the graph with two-step initialization manually (ugh)
- resolve the graph with two-step initialization automatically, ~approximately treating the graph of globals as a fixpoint
I haven’t put the time into deriving a nice little combinator for doing the two-step initialization yet; it’s a little different from the memoize() sorta thing because the result (the graph) is constant (& therefore takes no arguments). Seems solvable tho. Would love it if Swift would do this for me.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!